diff --git a/.env.development b/.env.development index 8621b8a7b..cfdd9ca03 100644 --- a/.env.development +++ b/.env.development @@ -134,7 +134,7 @@ PICTURE_DATABASE_URL=postgresql://picture:picturepassword@localhost:5434/picture # Storage Configuration (uses MinIO locally, Hetzner in production) # Uses shared S3_* variables from above - no project-specific override needed for local dev -PICTURE_STORAGE_PUBLIC_URL=http://localhost:9000/picture-images +PICTURE_STORAGE_PUBLIC_URL=http://localhost:9000/picture-storage # OAuth (optional - leave empty to disable) PICTURE_GOOGLE_CLIENT_ID= @@ -150,7 +150,7 @@ NUTRIPHI_APP_ID=nutriphi NUTRIPHI_GEMINI_API_KEY=your-gemini-api-key-here # S3 Storage (uses MinIO locally via shared S3_* variables, Hetzner in production) -NUTRIPHI_S3_PUBLIC_URL=http://localhost:9000/nutriphi-meals +NUTRIPHI_S3_PUBLIC_URL=http://localhost:9000/nutriphi-storage # ============================================ # ZITARE PROJECT @@ -174,6 +174,24 @@ VOXEL_LAVA_BACKEND_PORT=3010 VOXEL_LAVA_DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/voxel_lava VOXEL_LAVA_API_URL=http://localhost:3010 +# ============================================ +# CONTACTS PROJECT +# ============================================ + +CONTACTS_BACKEND_PORT=3015 +CONTACTS_DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/contacts + +# S3 Storage for contact photos +CONTACTS_S3_BUCKET=contacts-photos +CONTACTS_S3_PUBLIC_URL=http://localhost:9000/contacts-photos + +# ============================================ +# CALENDAR PROJECT +# ============================================ + +CALENDAR_BACKEND_PORT=3014 +CALENDAR_DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/calendar + # ============================================ # MANA-GAMES PROJECT # ============================================ diff --git a/CLAUDE.md b/CLAUDE.md index 1a180e1b3..26c6fa0b6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -393,11 +393,13 @@ pnpm docker:up | Bucket | Project | Purpose | |--------|---------|---------| -| `picture-images` | Picture | AI-generated images | -| `chat-files` | Chat | User file uploads | -| `manadeck-assets` | ManaDeck | Card/deck assets | -| `nutriphi-meals` | NutriPhi | Meal photos | -| `presi-slides` | Presi | Presentation slides | +| `picture-storage` | Picture | AI-generated images | +| `chat-storage` | Chat | User file uploads | +| `manadeck-storage` | ManaDeck | Card/deck assets | +| `nutriphi-storage` | NutriPhi | Meal photos | +| `presi-storage` | Presi | Presentation slides | +| `calendar-storage` | Calendar | Calendar attachments | +| `contacts-storage` | Contacts | Contact avatars/files | ### Usage in Backend diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index a0e84c4d5..be13e18bd 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -76,12 +76,14 @@ services: entrypoint: > /bin/sh -c " mc alias set myminio http://minio:9000 $${MINIO_ROOT_USER:-minioadmin} $${MINIO_ROOT_PASSWORD:-minioadmin}; - mc mb --ignore-existing myminio/picture-images; - mc mb --ignore-existing myminio/chat-files; - mc mb --ignore-existing myminio/manadeck-assets; - mc mb --ignore-existing myminio/nutriphi-meals; - mc mb --ignore-existing myminio/presi-slides; - mc anonymous set download myminio/picture-images; + mc mb --ignore-existing myminio/picture-storage; + mc mb --ignore-existing myminio/chat-storage; + mc mb --ignore-existing myminio/manadeck-storage; + mc mb --ignore-existing myminio/nutriphi-storage; + mc mb --ignore-existing myminio/presi-storage; + mc mb --ignore-existing myminio/calendar-storage; + mc mb --ignore-existing myminio/contacts-storage; + mc anonymous set download myminio/picture-storage; echo 'Buckets created successfully'; exit 0; " diff --git a/packages/shared-storage/README.md b/packages/shared-storage/README.md index d194d1477..a1a86f45e 100644 --- a/packages/shared-storage/README.md +++ b/packages/shared-storage/README.md @@ -22,11 +22,13 @@ The following buckets are automatically created: | Bucket | Project | Purpose | |--------|---------|---------| -| `picture-images` | Picture | Generated AI images | -| `chat-files` | Chat | User file uploads | -| `manadeck-assets` | ManaDeck | Card/deck assets | -| `nutriphi-meals` | NutriPhi | Meal photos | -| `presi-slides` | Presi | Presentation slides | +| `picture-storage` | Picture | Generated AI images | +| `chat-storage` | Chat | User file uploads | +| `manadeck-storage` | ManaDeck | Card/deck assets | +| `nutriphi-storage` | NutriPhi | Meal photos | +| `presi-storage` | Presi | Presentation slides | +| `calendar-storage` | Calendar | Calendar attachments | +| `contacts-storage` | Contacts | Contact avatars/files | ## Usage @@ -45,7 +47,7 @@ const result = await storage.upload(key, imageBuffer, { public: true, }); -console.log(result.url); // http://localhost:9000/picture-images/users/user-123/uuid.png +console.log(result.url); // http://localhost:9000/picture-storage/users/user-123/uuid.png // Download a file const buffer = await storage.download(key); @@ -85,6 +87,8 @@ import { createManaDeckStorage, createNutriPhiStorage, createPresiStorage, + createCalendarStorage, + createContactsStorage, } from '@manacore/shared-storage'; ``` @@ -110,8 +114,8 @@ S3_ACCESS_KEY=your-access-key S3_SECRET_KEY=your-secret-key # Optional: public URLs for CDN access -PICTURE_STORAGE_PUBLIC_URL=https://picture-images.fsn1.your-objectstorage.com -NUTRIPHI_S3_PUBLIC_URL=https://nutriphi-meals.fsn1.your-objectstorage.com +PICTURE_STORAGE_PUBLIC_URL=https://picture-storage.fsn1.your-objectstorage.com +NUTRIPHI_S3_PUBLIC_URL=https://nutriphi-storage.fsn1.your-objectstorage.com ``` ## Utilities diff --git a/packages/shared-storage/src/factory.ts b/packages/shared-storage/src/factory.ts index 58dc2e8a1..30d3357b0 100644 --- a/packages/shared-storage/src/factory.ts +++ b/packages/shared-storage/src/factory.ts @@ -105,3 +105,17 @@ export function createNutriPhiStorage(publicUrl?: string): StorageClient { export function createPresiStorage(): StorageClient { return createStorageClient({ name: BUCKETS.PRESI }); } + +/** + * Create a storage client for the Calendar project + */ +export function createCalendarStorage(): StorageClient { + return createStorageClient({ name: BUCKETS.CALENDAR }); +} + +/** + * Create a storage client for the Contacts project + */ +export function createContactsStorage(): StorageClient { + return createStorageClient({ name: BUCKETS.CONTACTS }); +} diff --git a/packages/shared-storage/src/index.ts b/packages/shared-storage/src/index.ts index 89c207fc0..368960fc2 100644 --- a/packages/shared-storage/src/index.ts +++ b/packages/shared-storage/src/index.ts @@ -10,6 +10,8 @@ export { createManaDeckStorage, createNutriPhiStorage, createPresiStorage, + createCalendarStorage, + createContactsStorage, } from './factory.js'; // Utilities diff --git a/packages/shared-storage/src/types.ts b/packages/shared-storage/src/types.ts index 96bae0884..88e794ead 100644 --- a/packages/shared-storage/src/types.ts +++ b/packages/shared-storage/src/types.ts @@ -76,11 +76,13 @@ export interface FileInfo { * Predefined bucket names for each project */ export const BUCKETS = { - PICTURE: 'picture-images', - CHAT: 'chat-files', - MANADECK: 'manadeck-assets', - NUTRIPHI: 'nutriphi-meals', - PRESI: 'presi-slides', + PICTURE: 'picture-storage', + CHAT: 'chat-storage', + MANADECK: 'manadeck-storage', + NUTRIPHI: 'nutriphi-storage', + PRESI: 'presi-storage', + CALENDAR: 'calendar-storage', + CONTACTS: 'contacts-storage', } as const; export type BucketName = (typeof BUCKETS)[keyof typeof BUCKETS];