Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ashcroft08/provesa-web/llms.txt

Use this file to discover all available pages before exploring further.

The site_config table provides a flexible key-value store for site-wide configuration settings. Each row represents a single configuration option.

Table: site_config

id
serial
required
Primary key. Auto-incrementing integer.Default: Auto-generated
key
text
required
Configuration key/identifier.Constraints:
  • .unique() - Each key must be unique
  • .notNull() - Required field
Examples:
  • "site_name"
  • "contact_email"
  • "google_analytics_id"
  • "maintenance_mode"
value
text
required
Configuration value stored as text.Note: All values are stored as strings. Convert to appropriate types when reading.

Usage Examples

Reading Configuration

import { siteConfig } from './schemas/site_config.schema';
import { db } from './db';
import { eq } from 'drizzle-orm';

// Get a single config value
const [config] = await db
  .select()
  .from(siteConfig)
  .where(eq(siteConfig.key, 'site_name'));

console.log(config?.value); // "PROVESA SCC"

// Get all config as an object
const allConfig = await db.select().from(siteConfig);
const configObject = Object.fromEntries(
  allConfig.map(c => [c.key, c.value])
);

console.log(configObject);
// {
//   site_name: "PROVESA SCC",
//   contact_email: "info@provesascc.com",
//   phone: "+593 6 280 0123",
//   maintenance_mode: "false"
// }

Setting Configuration

import { siteConfig } from './schemas/site_config.schema';
import { db } from './db';

// Insert or update a config value
await db
  .insert(siteConfig)
  .values({
    key: 'site_name',
    value: 'PROVESA SCC'
  })
  .onConflictDoUpdate({
    target: siteConfig.key,
    set: { value: 'PROVESA SCC' }
  });

Bulk Configuration Insert

import { siteConfig } from './schemas/site_config.schema';
import { db } from './db';

// Initialize multiple config values
await db.insert(siteConfig).values([
  { key: 'site_name', value: 'PROVESA SCC' },
  { key: 'site_tagline', value: 'Su distribuidor mayorista de confianza' },
  { key: 'contact_email', value: 'info@provesascc.com' },
  { key: 'contact_phone', value: '+593 6 280 0123' },
  { key: 'address', value: 'La Concordia, Santo Domingo de los Tsáchilas' },
  { key: 'business_hours', value: 'Lun-Vie: 8:00-18:00, Sáb: 8:00-14:00' },
  { key: 'google_analytics_id', value: 'G-XXXXXXXXXX' },
  { key: 'facebook_pixel_id', value: '' },
  { key: 'maintenance_mode', value: 'false' },
  { key: 'max_upload_size_mb', value: '10' }
]);

Common Configuration Keys

Here are typical configuration keys you might use:

General Site Info

KeyExample ValueDescription
site_name"PROVESA SCC"Company/site name
site_tagline"Su distribuidor mayorista"Tagline/slogan
site_description"Distribuidora mayorista..."Meta description
site_logo_url"/logo.png"Logo path
favicon_url"/favicon.ico"Favicon path

Contact Information

KeyExample ValueDescription
contact_email"info@provesascc.com"Main contact email
contact_phone"+593 6 280 0123"Main phone
whatsapp_number"+593987654321"WhatsApp contact
address"La Concordia, Ecuador"Physical address
business_hours"Lun-Vie: 8:00-18:00"Operating hours

Social Media

KeyExample ValueDescription
facebook_url"https://facebook.com/..."Facebook page
instagram_url"https://instagram.com/..."Instagram profile
tiktok_url"https://tiktok.com/@..."TikTok profile
youtube_url"https://youtube.com/..."YouTube channel

Analytics & Tracking

KeyExample ValueDescription
google_analytics_id"G-XXXXXXXXXX"GA4 measurement ID
google_tag_manager_id"GTM-XXXXXX"GTM container ID
facebook_pixel_id"1234567890"Meta Pixel ID

Feature Flags

KeyExample ValueDescription
maintenance_mode"true" / "false"Site maintenance
enable_chat"true" / "false"Live chat widget
enable_newsletter"true" / "false"Newsletter signup
enable_concursos"true" / "false"Contests feature

System Settings

KeyExample ValueDescription
max_upload_size_mb"10"Max file upload (MB)
session_timeout_hours"24"Session expiry
rate_limit_per_minute"60"API rate limit

Type-Safe Configuration Helper

Create a helper to get typed config values:
// lib/server/config.ts
import { db } from '$lib/server/db';
import { siteConfig } from '$lib/server/db/schemas/site_config.schema';
import { eq } from 'drizzle-orm';

// Cache config in memory
let configCache: Record<string, string> = {};
let cacheTime = 0;
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

export async function getConfig(key: string): Promise<string | null> {
  // Check cache
  if (Date.now() - cacheTime < CACHE_TTL && configCache[key]) {
    return configCache[key];
  }
  
  // Refresh cache if stale
  if (Date.now() - cacheTime >= CACHE_TTL) {
    const allConfig = await db.select().from(siteConfig);
    configCache = Object.fromEntries(allConfig.map(c => [c.key, c.value]));
    cacheTime = Date.now();
  }
  
  return configCache[key] || null;
}

export async function setConfig(key: string, value: string): Promise<void> {
  await db
    .insert(siteConfig)
    .values({ key, value })
    .onConflictDoUpdate({
      target: siteConfig.key,
      set: { value }
    });
  
  // Invalidate cache
  cacheTime = 0;
}

export async function getConfigBool(key: string, defaultValue = false): Promise<boolean> {
  const value = await getConfig(key);
  return value === 'true' || (value === null && defaultValue);
}

export async function getConfigNumber(key: string, defaultValue = 0): Promise<number> {
  const value = await getConfig(key);
  return value ? parseInt(value, 10) : defaultValue;
}

Using the Helper

import { getConfig, getConfigBool, getConfigNumber } from '$lib/server/config';

// Get string config
const siteName = await getConfig('site_name');

// Get boolean config
const isMaintenanceMode = await getConfigBool('maintenance_mode');

if (isMaintenanceMode) {
  return new Response('Site under maintenance', { status: 503 });
}

// Get number config
const maxUploadMB = await getConfigNumber('max_upload_size_mb', 10);

Database Migration

npm run db:generate
npm run db:migrate

Migration SQL

CREATE TABLE "site_config" (
  "id" serial PRIMARY KEY NOT NULL,
  "key" text NOT NULL UNIQUE,
  "value" text NOT NULL
);

-- Insert default configuration
INSERT INTO "site_config" (key, value) VALUES
  ('site_name', 'PROVESA SCC'),
  ('site_tagline', 'Su distribuidor mayorista de confianza'),
  ('contact_email', 'info@provesascc.com'),
  ('maintenance_mode', 'false');

Admin Panel Integration

// src/routes/admin/settings/+page.server.ts
import type { PageServerLoad, Actions } from './$types';
import { db } from '$lib/server/db';
import { siteConfig } from '$lib/server/db/schemas/site_config.schema';
import { setConfig } from '$lib/server/config';

export const load: PageServerLoad = async () => {
  const config = await db.select().from(siteConfig);
  return {
    config: Object.fromEntries(config.map(c => [c.key, c.value]))
  };
};

export const actions = {
  update: async ({ request }) => {
    const data = await request.formData();
    
    for (const [key, value] of data.entries()) {
      await setConfig(key, value.toString());
    }
    
    return { success: true };
  }
} satisfies Actions;

Best Practices

When to Use site_config:✅ Use for simple key-value settings
✅ Use for feature flags
✅ Use for text-based configuration
❌ Don’t use for complex structured data (use dedicated tables)
❌ Don’t use for frequently changing data
❌ Don’t use for sensitive secrets (use environment variables)
Performance Tips:
  1. Cache config values in memory (see helper example)
  2. Load all config at startup for frequently accessed values
  3. Use a CDN for static config that rarely changes
Security:
  • Never store API keys, passwords, or secrets in this table
  • Use environment variables for sensitive configuration
  • Implement proper admin access controls
  • Validate and sanitize values before saving

Build docs developers (and LLMs) love