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:
2026-06-05 02:33:05 +00:00
parent 367a5625f3
commit 456b5b1375
42 changed files with 973 additions and 5608 deletions
+31
View File
@@ -0,0 +1,31 @@
"use server";
import { Pool } from "pg";
import { revalidatePath } from "next/cache";
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
export type UpdateAdminProfileResult =
| { success: true }
| { success: false; error: string };
export async function updateAdminProfileAction(
id: string,
displayName: string | null,
phoneNumber: string | null
): Promise<UpdateAdminProfileResult> {
try {
await pool.query("SELECT update_admin_user($1, $2, $3)", [
id,
displayName,
phoneNumber,
]);
revalidatePath("/admin/me");
return { success: true };
} catch (e: unknown) {
const message = e instanceof Error ? e.message : "Failed to update profile";
return { success: false, error: message };
}
}