Add MinIO storage + replace Supabase Storage with S3 SDK
- New: src/lib/storage.ts — S3-compatible client, uploadFile/deleteFile/listFiles/publicUrl helpers, bucket constants - New: docker-compose adds minio + minio_init services - Replaced Supabase fetch PUTs in: - src/actions/brand-settings.ts (3 uploaders) - src/actions/products/upload-image.ts - src/actions/communications/import-contacts.ts - src/app/api/water-photo-upload/route.ts - Replaced hardcoded Supabase URLs in: - src/components/storefront/TuxedoVideoHero.tsx - src/components/time-tracking/TimeTrackingFieldClient.tsx - src/app/tuxedo/about/page.tsx - src/lib/email-service.ts (4 occurrences) - Added @aws-sdk/client-s3 + @aws-sdk/s3-request-presigner - .env.example adds MinIO + storage vars - Migration cleanup: deleted BUNDLE_018_042, 4 XXX drafts, 087/145/099-contact storage migrations - Migration patches: 006 STATIC→STABLE, 135 param reordering - Preflight: added pgcrypto extension, removed storage stub - Verified: MinIO upload/list/delete round-trip works against local instance
This commit is contained in:
@@ -1,63 +1,41 @@
|
||||
"use server";
|
||||
|
||||
import { createServerClient } from "@supabase/ssr";
|
||||
import { cookies } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
import { Pool } from "pg";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
});
|
||||
|
||||
const DEV_ADMIN_UID = "dev-user-00000000-0000-0000-0000-000000000001";
|
||||
|
||||
export async function forceAdminLogin(): Promise<{ success: boolean; uid?: string; error?: string }> {
|
||||
const cookieStore = await cookies();
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
|
||||
try {
|
||||
// Upsert dev platform_admin record
|
||||
const res = await pool.query(
|
||||
`INSERT INTO admin_users (
|
||||
user_id, brand_id, role, active,
|
||||
can_manage_products, can_manage_stops, can_manage_orders, can_manage_pickup,
|
||||
can_manage_messages, can_manage_refunds, can_manage_users, can_manage_water_log,
|
||||
can_manage_reports, can_manage_settings, must_change_password
|
||||
) VALUES (
|
||||
$1, NULL, 'platform_admin', true,
|
||||
true, true, true, true,
|
||||
true, true, true, true,
|
||||
true, true, false
|
||||
)
|
||||
ON CONFLICT (user_id) DO UPDATE SET active = EXCLUDED.active
|
||||
RETURNING id, role`,
|
||||
[DEV_ADMIN_UID]
|
||||
);
|
||||
|
||||
const response = NextResponse.next();
|
||||
const supabase = createServerClient(supabaseUrl, supabaseAnonKey, {
|
||||
cookies: {
|
||||
getAll() { return cookieStore.getAll(); },
|
||||
setAll(cookiesToSet, headers) {
|
||||
cookiesToSet.forEach(({ name, value, options }) => {
|
||||
response.cookies.set(name, value, options);
|
||||
});
|
||||
Object.entries(headers).forEach(([key, value]) => {
|
||||
response.headers.set(key, value);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Upsert dev platform_admin record
|
||||
const { data: existing } = await supabase
|
||||
.from("admin_users")
|
||||
.select("id, role")
|
||||
.eq("user_id", DEV_ADMIN_UID)
|
||||
.single();
|
||||
|
||||
if (!existing) {
|
||||
const { error: insertError } = await supabase
|
||||
.from("admin_users")
|
||||
.insert({
|
||||
user_id: DEV_ADMIN_UID,
|
||||
brand_id: null,
|
||||
role: "platform_admin",
|
||||
active: true,
|
||||
can_manage_products: true,
|
||||
can_manage_stops: true,
|
||||
can_manage_orders: true,
|
||||
can_manage_pickup: true,
|
||||
can_manage_messages: true,
|
||||
can_manage_refunds: true,
|
||||
can_manage_users: true,
|
||||
can_manage_water_log: true,
|
||||
can_manage_reports: true,
|
||||
can_manage_settings: true,
|
||||
must_change_password: false,
|
||||
});
|
||||
|
||||
if (insertError) {
|
||||
return { success: false, error: insertError.message };
|
||||
if (res.rows.length === 0) {
|
||||
return { success: false, error: "Failed to upsert dev admin" };
|
||||
}
|
||||
}
|
||||
|
||||
return { success: true, uid: DEV_ADMIN_UID };
|
||||
return { success: true, uid: DEV_ADMIN_UID };
|
||||
} catch (e: unknown) {
|
||||
const message = e instanceof Error ? e.message : "Unknown error";
|
||||
return { success: false, error: message };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user