home_room_modules
Overview
The home_room_modules table stores individual content blocks placed within a user's HomeRoom. Each module has a type (one of: about, mebook, photos, links, featured_posts, guestbook), display order, enable/collapse toggles, per-module visibility controls, and optional configuration JSON. Layout positioning columns (added by 20260202_room_layouts.sql) support freeform, grid, and mindmap layout modes.
Default modules are automatically created for each new user via a trigger on the profiles table. A unique constraint on (user_id, module_type) ensures one module of each type per user.
Schema
-- From 20260130_homeroom_foundation.sql
CREATE TABLE home_room_modules (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE NOT NULL,
-- Module identification
module_type TEXT NOT NULL CHECK (module_type IN (
'about', 'mebook', 'photos', 'links', 'featured_posts', 'guestbook'
)),
-- Display settings
order_index INT NOT NULL DEFAULT 0,
is_enabled BOOLEAN DEFAULT TRUE,
default_collapsed BOOLEAN DEFAULT FALSE,
custom_title TEXT,
-- Visibility
visibility_scope TEXT DEFAULT 'inherit' CHECK (visibility_scope IN (
'inherit', 'public', 'friends', 'circles', 'specific'
)),
allowed_viewer_ids UUID[] DEFAULT NULL,
-- Module-specific config
config_json JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, module_type),
-- Layout positioning (added by 20260202_room_layouts.sql)
position_x INT DEFAULT NULL,
position_y INT DEFAULT NULL,
width INT DEFAULT NULL,
height INT DEFAULT NULL,
grid_column INT DEFAULT NULL,
grid_row INT DEFAULT NULL,
grid_span INT DEFAULT 1,
connected_to UUID[] DEFAULT NULL,
z_index INT DEFAULT 0
);
Columns
| Column | Type | Nullable | Default | Description |
|---|---|---|---|---|
id | uuid | No | gen_random_uuid() | Primary key |
user_id | uuid | No | -- | Module owner, references profiles(id) |
module_type | text | No | -- | Module type: about, mebook, photos, links, featured_posts, guestbook |
order_index | int | No | 0 | Sort order in single-column layout |
is_enabled | boolean | No | TRUE | Whether module is active |
default_collapsed | boolean | No | FALSE | Whether module starts collapsed |
custom_title | text | Yes | -- | Optional override of default module title |
visibility_scope | text | No | 'inherit' | Visibility: inherit, public, friends, circles, specific |
allowed_viewer_ids | uuid[] | Yes | NULL | Specific user IDs allowed when scope is 'specific' |
config_json | jsonb | No | '{}' | Module-specific configuration data |
created_at | timestamptz | No | NOW() | Creation timestamp |
updated_at | timestamptz | No | NOW() | Last update timestamp (auto-updated by trigger) |
position_x | int | Yes | NULL | X position for freeform/mindmap layouts |
position_y | int | Yes | NULL | Y position for freeform/mindmap layouts |
width | int | Yes | NULL | Custom width override |
height | int | Yes | NULL | Custom height override |
grid_column | int | Yes | NULL | Specific column assignment for column layouts |
grid_row | int | Yes | NULL | Specific row assignment for grid layouts |
grid_span | int | No | 1 | Number of columns to span |
connected_to | uuid[] | Yes | NULL | Array of module IDs this connects to (mindmap) |
z_index | int | No | 0 | Stacking order for overlapping modules |
Constraints
UNIQUE(user_id, module_type)-- One module of each type per usermodule_typemust be one of:about,mebook,photos,links,featured_posts,guestbookvisibility_scopemust be one of:inherit,public,friends,circles,specific
Triggers
-- Auto-updates updated_at on row changes (reuses the home_room_settings function)
CREATE TRIGGER home_room_modules_updated
BEFORE UPDATE ON home_room_modules
FOR EACH ROW EXECUTE FUNCTION update_home_room_settings_updated_at();
Default Modules
When a new profile is created, the following modules are auto-inserted:
| module_type | order_index | is_enabled |
|---|---|---|
about | 0 | TRUE |
photos | 1 | TRUE |
mebook | 2 | FALSE |
links | 3 | TRUE |
featured_posts | 4 | TRUE |
guestbook | 5 | FALSE |
RLS Policies
-- SELECT: Visibility based on module scope, friendship, and specific viewer list
CREATE POLICY "Users can view modules based on visibility"
ON home_room_modules FOR SELECT TO authenticated
USING (
user_id = auth.uid()
OR (
is_enabled = TRUE
AND (
visibility_scope = 'public'
OR visibility_scope = 'inherit'
OR (visibility_scope = 'friends' AND user_id IN (
SELECT CASE
WHEN requester_id = auth.uid() THEN addressee_id
ELSE requester_id
END
FROM friendships
WHERE status = 'accepted'
AND (requester_id = auth.uid() OR addressee_id = auth.uid())
))
OR (visibility_scope = 'specific' AND auth.uid() = ANY(allowed_viewer_ids))
)
)
);
-- ALL (INSERT/UPDATE/DELETE): Only owner can manage their own modules
CREATE POLICY "Users can manage own modules"
ON home_room_modules FOR ALL TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
Indexes
CREATE INDEX idx_home_room_modules_user_id ON home_room_modules(user_id);
CREATE INDEX idx_home_room_modules_type ON home_room_modules(module_type);
Related
- home_room_settings -- Parent room configuration
- profiles -- Module owner
- profile_photos -- Photos data for the photos module
- profile_links -- Links data for the links module
- featured_posts -- Featured posts data for the featured_posts module
Last updated: 2026-02-07