Site Configuration
Dynamic site configuration system for maintenance mode, feature flags, and API control.
The site_config table gives admins runtime control over the platform without deploying code. Need to put the site into maintenance mode? Disable signups temporarily? Show a banner message? Update a row in site_config and the change takes effect immediately.
The middleware checks these values on every request, so toggling maintenance_mode to true instantly redirects all non-admin users to the maintenance page. Feature flags like signups_enabled and api_enabled gate specific functionality. Debug mode adds diagnostic headers and shows a "Development Mode" badge in the navigation.
All values are stored as JSONB and have sensible defaults inserted by the migration. Only admins can write to the table; everyone can read (needed for middleware and page rendering).
Database Schema
Table Structure
CREATE TABLE site_config (
key TEXT PRIMARY KEY,
value JSONB NOT NULL,
description TEXT,
updated_by UUID REFERENCES users(id) ON DELETE SET NULL,
updated_at TIMESTAMPTZ DEFAULT NOW()
);Configuration Keys
| Key | Type | Default | Description |
|---|---|---|---|
maintenance_mode | boolean | false | When enabled, redirects users to maintenance page and disables non-critical routes |
debug_mode | boolean | false | When enabled, shows debug information and additional error details. Also shows "Development Mode" badge on welcome page |
onboarding_enabled | boolean | true | Controls whether the onboarding flow is accessible |
signups_enabled | boolean | true | Controls whether new user signups are allowed |
api_enabled | boolean | true | Controls API access |
site_message | string | "" | Optional site-wide message to display to users |
app_version | string | "0.1.0" | Application version displayed in footer |
api_version | string | "v1" | API version displayed in footer |
Setup Instructions
Verify Default Values
Check that default values were inserted:
SELECT * FROM site_config ORDER BY key;You should see all 6 configuration keys with their default values.
Usage
Reading Configuration
In Server Components
import { getSiteConfig, getSiteConfigValue } from "@/lib/supabase/config";
// Get all config
const config = await getSiteConfig();
if (config.maintenance_mode) {
// Handle maintenance mode
}
// Get specific value
const signupsEnabled = await getSiteConfigValue("signups_enabled");In API Routes
import { getSiteConfigValue } from "@/lib/supabase/config";
export async function POST() {
const apiEnabled = await getSiteConfigValue("api_enabled");
if (!apiEnabled) {
return NextResponse.json(
{ error: "API access is currently disabled" },
{ status: 503 }
);
}
// ... rest of handler
}Updating Configuration
Via SQL (Admin Only)
-- Enable maintenance mode
UPDATE site_config
SET value = 'true'::jsonb, updated_at = NOW()
WHERE key = 'maintenance_mode';
-- Disable signups
UPDATE site_config
SET value = 'false'::jsonb, updated_at = NOW()
WHERE key = 'signups_enabled';
-- Set site message
UPDATE site_config
SET value = '"Scheduled maintenance on Dec 25th"'::jsonb, updated_at = NOW()
WHERE key = 'site_message';Via Admin Interface (Recommended)
Admins can update configuration through the admin dashboard (to be implemented in admin page).
Feature Implementation
Maintenance Mode
Location: lib/supabase/middleware.ts
When maintenance_mode is true:
- All routes redirect to
/maintenancepage - Admins can bypass maintenance mode
- Static assets and auth routes are excluded from redirect
Maintenance Page: app/maintenance/page.tsx
- Displays maintenance message
- Shows site_message if configured
- Allows admins to continue working
Debug Mode
Location:
lib/supabase/middleware.ts- Adds debug headerscomponents/DevModeBadge.tsx- Shows badge on welcome pagecomponents/Navigation.tsx- Displays badge in navigation
When debug_mode is true:
- Adds
X-Debug-Mode: enabledheader to responses - Shows "Development Mode" badge in navigation header on
/welcomepage - Can be used by frontend to show additional debug information
Onboarding Control
Location: app/onboarding/page.tsx
When onboarding_enabled is false:
- Onboarding page redirects to
/explorer - Users skip onboarding flow
Signups Control
Location:
app/login/page.tsx- Shows disabled messageapp/auth/login/route.ts- Blocks authentication
When signups_enabled is false:
- Login form shows "Signups Temporarily Disabled" message
- Sign in button is disabled
- OAuth flow is blocked
API Control
Location: All API routes in app/api/
When api_enabled is false:
- All API endpoints return
503 Service Unavailable - Error message: "API access is currently disabled"
Affected routes:
/api/plugins/install/[id]/api/plugins/by-id/[id]/favorite/toggle/api/plugins/[org]/[team]/[plugin]/api/mcp/token/api/mcp/deeplink/api/admin/publish-plugin
Site Message
Location: app/maintenance/page.tsx
When site_message is set:
- Displayed on maintenance page
- Can be used for announcements or important notices
Version Information
Location: components/Footer.tsx
Version information is displayed in the footer:
app_version- Application version (e.g., "0.1.0")api_version- API version (e.g., "v1")
Footer displays: App v\{app_version\} • API \{api_version\}
Development vs Production Defaults
Development
UPDATE site_config SET value = 'true'::jsonb WHERE key = 'debug_mode';
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'maintenance_mode';Production
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'debug_mode';
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'maintenance_mode';Admin Management
Check Current Configuration
SELECT key, value, description, updated_at
FROM site_config
ORDER BY key;Update Configuration (Admin Only)
-- Example: Enable maintenance mode
UPDATE site_config
SET
value = 'true'::jsonb,
updated_by = auth.uid(),
updated_at = NOW()
WHERE key = 'maintenance_mode';Reset to Defaults
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'maintenance_mode';
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'debug_mode';
UPDATE site_config SET value = 'true'::jsonb WHERE key = 'onboarding_enabled';
UPDATE site_config SET value = 'true'::jsonb WHERE key = 'signups_enabled';
UPDATE site_config SET value = 'true'::jsonb WHERE key = 'api_enabled';
UPDATE site_config SET value = '""'::jsonb WHERE key = 'site_message';
UPDATE site_config SET value = '"0.1.0"'::jsonb WHERE key = 'app_version';
UPDATE site_config SET value = '"v1"'::jsonb WHERE key = 'api_version';Security
RLS Policies
- Read: Everyone can read config values (needed for middleware/pages)
- Write: Only admins can update config values
Admin Bypass
- Admins can bypass maintenance mode
- Admin check is performed in middleware before redirect
Troubleshooting
Config Not Found
If config values are not found, the system uses safe defaults:
maintenance_mode:falsedebug_mode:falseonboarding_enabled:truesignups_enabled:trueapi_enabled:truesite_message:""
Performance Considerations
- Config is checked on every request in middleware
- Consider caching config values if performance becomes an issue
- Database queries are lightweight (single row lookup by primary key)
Testing
-- Test maintenance mode
UPDATE site_config SET value = 'true'::jsonb WHERE key = 'maintenance_mode';
-- Visit any page (should redirect to /maintenance)
-- As admin, should still be able to access pages
-- Test signups disabled
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'signups_enabled';
-- Try to sign in (should show disabled message)
-- Test API disabled
UPDATE site_config SET value = 'false'::jsonb WHERE key = 'api_enabled';
-- Try any API endpoint (should return 503)Related Files
- Migration:
supabase/migrations/001_init.sql - Config utility:
lib/supabase/config.ts - Middleware:
lib/supabase/middleware.ts - Maintenance page:
app/maintenance/page.tsx - Onboarding page:
app/onboarding/page.tsx - Login page:
app/login/page.tsx - API routes:
app/api/**/*.ts