Data Modeling
Blogify uses a relational data model managed via Supabase (PostgreSQL). The architecture separates identity management (Supabase Auth) from application data (PostgreSQL tables), ensuring that user profiles and content are strictly linked to authenticated sessions.
Core Entities
The system revolves around two primary entities: Users and Posts.
User Model
The User model stores public profile information. While authentication is handled by Supabase Auth, the application maintains a users table in the public schema to store display-related metadata.
| Field | Type | Description |
| :--- | :--- | :--- |
| id | UUID | Primary Key. Matches the auth.users.id from Supabase. |
| name | String | The display name chosen by the user. |
| email | String | The user's registered email address. |
| profile_picture_url | String? | URL to the avatar stored in Supabase Storage. |
| created_at | Timestamp | Automatic timestamp of account creation. |
Post Model
The Post model stores the core content of the platform, supporting Markdown and LaTeX (KaTeX) formatting.
| Field | Type | Description |
| :--- | :--- | :--- |
| id | UUID | Unique identifier for the blog post. |
| user_id | UUID | Foreign Key referencing users.id. |
| title | String | The title of the post. |
| content | String | The body text (supports Markdown and Math syntax). |
| tags | String[] | An array of strings used for filtering and discovery. |
| image_url | String? | URL for the post's featured image. |
| created_at | Timestamp | Creation date. |
| updated_at | Timestamp? | Date of the last modification. |
TypeScript Interfaces
The frontend uses TypeScript interfaces to ensure type safety when interacting with the FastAPI backend. These models represent the data structures returned by the API.
Post Object
Used for rendering posts in the feed and individual post pages.
export interface Post {
id: string;
title: string;
content: string;
user_id: string;
tags: string[];
image_url?: string;
created_at: string;
updated_at: string | null;
}
User Profile
Used for profile pages and author attribution on posts.
export interface User {
id: string;
name: string;
email: string;
profile_picture_url?: string;
created_at: string;
}
Input Schemas (DTOs)
To maintain strict data integrity, Blogify uses specific shapes for creating and updating resources.
Creating a Post
When sending a POST request to /posts, the following structure is required:
export interface PostCreate {
title: string;
content: string;
user_id: string;
tags?: string[];
image_url?: string;
}
Updating a Post
The PUT request for /posts/{id} allows for partial updates. Only the fields provided will be modified.
export interface PostUpdate {
title?: string;
content?: string;
tags?: string[];
image_url?: string;
}
Relationships & Integrity
- One-to-Many Relationship: A single
Usercan author multiplePosts. This is enforced by theuser_idforeign key in thepoststable. - Auth Synchronization: The application relies on Supabase Auth. When a user signs up, their unique
UUIDis used to create their record in the publicuserstable, ensuring that all application data is tied to a verified identity. - Cascading Deletes: (Recommended) Deleting a user profile typically handles associated content via Row Level Security (RLS) policies or database triggers to maintain referential integrity.
Storage Objects
Images are not stored directly in the database. Instead:
- Avatars: Stored in the
avatarsbucket. - Post Images: Stored in the
imagesbucket. The database only stores the Public URL generated after a successful upload to Supabase Storage.