Skip to main content
GET
/
api
/
admin
/
seed-locations
Seed Locations
curl --request GET \
  --url https://api.example.com/api/admin/seed-locations
{
  "success": true,
  "seeded": {
    "brands": [
      "<string>"
    ],
    "locations": [
      "<string>"
    ]
  }
}

Seed Locations

Initialize the database with predefined brands and locations. This endpoint is typically used during initial setup or testing.

Endpoint

GET /api/admin/seed-locations

Authentication

Requires canViewSettings permission (admin or super_admin only).
await requirePermission("canViewSettings");

Seeded Data

Brands

NameSlug
La Tascala-tasca
El Patioel-patio
La Brisa Madridla-brisa

Locations

NameCityAddressBrand
La Tasca Madrid · CentroMadridCalle Gran Vía, 25La Tasca
La Tasca Madrid · SalamancaMadridCalle Serrano, 3La Tasca
La Tasca Barcelona · EixampleBarcelonaCarrer de Provença, 230La Tasca
El Patio BarcelonaBarcelonaCarrer del Consell de Cent, 302El Patio
La Brisa MadridMadridPaseo de la Castellana, 200La Brisa

Response

success
boolean
Whether seeding completed successfully
seeded
object
Details of seeded records

Example Request

curl -X GET https://your-domain.com/api/admin/seed-locations \
  -H "Cookie: your-session-cookie"

Example Response

{
  "success": true,
  "seeded": {
    "brands": ["La Tasca", "El Patio", "La Brisa Madrid"],
    "locations": [
      "La Tasca Madrid · Centro",
      "La Tasca Madrid · Salamanca",
      "La Tasca Barcelona · Eixample",
      "El Patio Barcelona",
      "La Brisa Madrid"
    ]
  }
}

Error Response

{
  "success": false,
  "error": "Error message",
  "status": 500
}

Implementation Details

The endpoint:
  1. Uses service role key to bypass RLS
  2. Checks for existing brands/locations by slug/name
  3. Only creates records that don’t already exist
  4. Returns arrays of newly created items (not existing ones)

Source Code Reference

app/api/admin/seed-locations/route.ts
import { createClient } from "@supabase/supabase-js";
import { requirePermission } from "@/lib/authz";

export async function GET() {
    await requirePermission("canViewSettings");
    
    const supabase = createClient(
        process.env.NEXT_PUBLIC_SUPABASE_URL!,
        process.env.SUPABASE_SERVICE_ROLE_KEY!
    );

    // Seed brands
    for (const brand of BRANDS) {
        const { data: existing } = await supabase
            .from('brands')
            .select('id')
            .eq('slug', brand.slug)
            .maybeSingle();

        if (!existing) {
            await supabase.from('brands').insert({
                name: brand.name,
                slug: brand.slug
            });
        }
    }

    // Seed locations linked to brands
    for (const loc of LOCATIONS) {
        const brandId = allBrands.find(b => b.slug === loc.brand_slug)?.id;
        
        const { data: existingLoc } = await supabase
            .from('locations')
            .select('id')
            .eq('name', loc.name)
            .maybeSingle();

        if (!existingLoc) {
            await supabase.from('locations').insert({
                name: loc.name,
                city: loc.city,
                address: loc.address,
                brand_id: brandId
            });
        }
    }
}

Idempotency

This endpoint is idempotent - running it multiple times will not create duplicates. It only creates brands and locations that don’t already exist.

Use Cases

  • Initial database setup for new installations
  • Development/testing environment setup
  • Restore default locations after testing
  • Demo data creation
This endpoint uses the service role key and bypasses all RLS policies. Use with caution in production environments.

Build docs developers (and LLMs) love