# Plan: Rename & Redesign `create_menu_image` → `create_restaurant_offer`

## Overview

The service changes its purpose entirely:

- **Before:** Generate a full restaurant menu poster (all menu items, many rows, multi-column layout)
- **After:** Generate a **themed promotional offer poster** for a restaurant occasion (Valentine's Day, 8 March, Daily Special, etc.) with a small curated set of dishes + drinks, a mood-matching visual theme, and logo always pinned to the top

---

## Concept: What Is a "Restaurant Offer"?

A restaurant offer is a **limited, occasion-specific promotion** — not a full menu.

Examples:
- **Valentine's Day offer** – 2 dishes + 1 dessert + 1 cocktail, deep red/rose theme with hearts
- **8 March (Women's Day)** – 3 dishes + 1 mocktail + 1 dessert, rose gold / roses / spring flowers
- **Daily special** – 1 soup + 1 main + 1 drink, clean modern layout
- **Christmas menu** – 3 dishes + 2 drinks, dark red/gold/snow theme

Key differences from the old menu poster:
| Old (menu poster) | New (offer poster) |
|---|---|
| Full menu, 20–60+ items | 3–8 curated items max |
| Multi-column to fit everything | Single column or 2 columns, generous spacing |
| Cuisine auto-detected from items | **Occasion/theme** drives the design |
| Neutral or cuisine-flavored bg | **Themed visual background** (hearts, roses, snowflakes…) |
| Logo top-right, auto-sized | **Logo always top-center or top-left, prominent** |
| User style tip is optional extra | **User visual prompt is a first-class input** |

---

## Files to Change

### 1. Rename service folder
```
app/services/create_menu_image/   →   app/services/create_restaurant_offer/
```
All internal imports update accordingly.

### 2. Rename config file
```
config/services/create_menu_image.yaml   →   config/services/create_restaurant_offer.yaml
```

### 3. Files to update inside the new folder

| File | Changes |
|---|---|
| `models/requests.py` | New request model (see below) |
| `models/responses.py` | Rename class; keep `image_url` + `version` |
| `service.py` | Full rewrite of logic (see below) |
| `routes.py` | Rename router prefix, function names, service ref |
| `config.py` | Rename class + config key from `create_menu_image` → `create_restaurant_offer` |
| `__init__.py` | No functional change |
| `models/__init__.py` | No functional change |

### 4. `app/main.py`
- Update all imports from `create_menu_image` → `create_restaurant_offer`
- Update service init block (class name, config key, log label)
- Update startup log services list
- Update service token key (`create_restaurant_offer`)

### 5. `app/shared/middleware/auth.py`
- Add `verify_create_restaurant_offer_auth` function
- Can keep old one during transition or replace

---

## New Request Model — `CreateRestaurantOfferRequest`

```python
class CreateRestaurantOfferRequest(BaseModel):
    z_id: str                      # Restaurant identifier (storage path)
    occasion: str                  # e.g. "Valentine's Day", "8 March", "Daily Special"
    offer_items: str               # Curated list: dishes + drinks (plain text, 3–8 items)
    logo_image_url: str            # Public URL to restaurant logo
    visual_prompt: Optional[str]   # User description: "romantic, dark red, candles"
    model: Optional[str]           # Optional OpenAI model override
```

**Aliases** (camelCase for API compatibility):
- `zId` → `z_id`
- `offerItems` → `offer_items`
- `logoImageUrl` → `logo_image_url`
- `visualPrompt` → `visual_prompt`

---

## Theme System — Occasion → Visual Design

Replace the cuisine detection + cuisine design dicts with an **occasion theme map**.

### Predefined Themes

| Occasion keywords | Theme |
|---|---|
| `valentine`, `valentine's day`, `love` | Deep crimson/rose, hearts, rose petals, candlelight bokeh, elegant serif |
| `8 march`, `women's day`, `womens day`, `international women` | Rose gold + soft green, spring flowers, roses, light romantic serif |
| `christmas`, `xmas`, `new year` | Dark red + gold + white, snowflakes, pine, rich festive feel |
| `easter` | Pastel yellows/greens/lilac, spring blossoms, light airy design |
| `halloween` | Dark orange + black + purple, pumpkins, spooky gothic |
| `summer special`, `bbq`, `grill` | Warm orange/yellow, sun, outdoor terrace feel |
| `daily special`, `daily menu`, `lunch` | Clean minimal, white + brand colors, modern sans-serif |
| `birthday`, `celebration`, `anniversary` | Gold + champagne, confetti, festive |
| `seasonal`, `autumn`, `fall` | Warm amber/brown, leaves, cozy |

If occasion doesn't match any keyword → use a **clean elegant neutral** theme with brand colors.

### Theme Object Structure

```python
@dataclass
class OfferTheme:
    palette: str          # e.g. "deep crimson, rose gold, soft pink"
    background_scene: str # e.g. "romantic candlelit table with rose petals"
    decorative_elements: str  # e.g. "floating hearts, rose petals border"
    font_style: str       # e.g. "elegant thin serif (Cormorant style)"
    mood: str             # e.g. "romantic, intimate, luxurious"
```

---

## New Service Logic — `CreateRestaurantOfferService`

### `create_restaurant_offer(request)` — main flow

1. **Detect theme** from `request.occasion` → match to `OfferTheme`
2. **Download logo** → extract brand colors (keep existing `_extract_brand_colors`)
3. **Pick canvas size** → always `1024x1536` (tall portrait, generous offer layout)
4. **Build prompt** → combine theme + offer items + logo instruction + user visual prompt
5. **Generate image** via OpenAI `gpt-image-1`
6. **Overlay logo** top-center (update `_compose_with_logo` to place logo centered at top, not top-right)
7. **Persist** and return URL

### Remove from old service (no longer needed)
- `_detect_cuisine()` — replaced by `_detect_theme()`
- `_count_menu_lines()` — offer is small, no need to count
- `_format_menu_structured()` — offer items are few, no complex formatting
- `_pick_size()` — always `1024x1536` for offers
- `_CUISINE_KEYWORDS` dict
- `_CUISINE_DESIGN` dict
- Multi-column layout logic

### Keep from old service
- `_extract_brand_colors()` — still useful
- `_remove_white_background()` — for logo compositing
- `_sample_background_color()` — still useful
- `_compose_with_logo()` — update placement to **top-center**
- `_sanitize_z_id()` — unchanged
- `_build_storage_target()` — update filename prefix: `offer_` instead of `menu_`
- `_download_image_bytes()` — unchanged
- `_persist_generated_image()` — unchanged

---

## New Prompt Strategy — `_build_prompt()`

The prompt must communicate:
1. **Occasion and mood** — AI should feel the occasion
2. **Themed visual background** — entire image, not just text layout
3. **Decorative elements** matching the occasion
4. **Small curated offer** — few items with generous spacing
5. **Drinks section** clearly separated
6. **Logo at top** — prominent, always visible
7. **User's visual prompt** — first-class creative direction

### Prompt Template (pseudocode)

```
Create a premium restaurant promotional offer poster for [{occasion}].

VISUAL THEME & BACKGROUND:
- The entire image must feel like [{theme.mood}]
- Background: [{theme.background_scene}], rich and atmospheric, not just a blur
- Color palette: [{theme.palette}] — use throughout the entire design
- Decorative elements: [{theme.decorative_elements}] woven into the composition
- Fonts: [{theme.font_style}] for headings, clean readable weight for items
- Brand accent colors: [{brand_colors}] for borders, dividers, and highlights

LOGO (MANDATORY):
- Place the restaurant logo at the very TOP CENTER of the poster
- Logo must be prominent — at least 15% of poster width
- Below the logo: occasion title in elegant large lettering

OFFER CONTENT:
- Present as a curated special offer, NOT a full menu
- [{offer_items}] — each item on its own line with generous spacing
- Separate FOOD items from DRINKS with a decorative divider
- Prices shown as €X.XX, right-aligned or centered under each item
- Leave breathing room between items — this is a premium promotional poster

USER DIRECTION:
- [{visual_prompt if provided}]

LAYOUT RULES:
- Tall portrait canvas (1024×1536)
- Top section (~20%): logo + occasion title
- Middle section (~65%): offer items, richly themed
- Bottom section (~15%): tagline or empty with decorative element
- No clutter — white space is intentional and premium
- Make it look like a real restaurant event promotion, NOT a price list
```

---

## Logo Placement Change

**Old:** Top-right corner (small badge)
**New:** Top-center, prominent

Update `_compose_with_logo()`:
```python
# New placement: centered horizontally, near top
logo_x = (width - new_w) // 2
logo_y = margin
```

---

## Config File — `create_restaurant_offer.yaml`

```yaml
enabled: true

auth:
  bearer_token_env: "CREATE_RESTAURANT_OFFER_SERVICE_KEY"

openai:
  api_key_env: "OPENAI_API_KEY_CREATE_RESTAURANT_OFFER"
  models:
    create_restaurant_offer: "gpt-image-1"
  timeout: 60.0
  size: "auto"
  quality: "high"

storage:
  root_dir: "menues"
  url_prefix: "/menues"
```

---

## API Route Change

| | Old | New |
|---|---|---|
| Router prefix | `/menu-image` | `/restaurant-offer` |
| Endpoint | `POST /menu-image/create` | `POST /restaurant-offer/create` |
| Auth dependency | `verify_create_menu_image_auth` | `verify_create_restaurant_offer_auth` |
| Service token env | `CREATE_MENU_IMAGE_SERVICE_KEY` | `CREATE_RESTAURANT_OFFER_SERVICE_KEY` |

---

## `main.py` Auth Token Block Update

```python
service_tokens = {
    ...
    "create_restaurant_offer": get_env_var("CREATE_RESTAURANT_OFFER_SERVICE_KEY", required=False),
}
```

---

## Execution Order (Implementation Steps)

1. **Create** new folder `app/services/create_restaurant_offer/` with all files
2. **Write** `models/requests.py` — new `CreateRestaurantOfferRequest`
3. **Write** `models/responses.py` — rename to `CreateRestaurantOfferResponse`
4. **Write** `config.py` — rename class, update config key
5. **Write** `service.py` — new `CreateRestaurantOfferService` with theme system
6. **Write** `routes.py` — updated prefix, imports, service call
7. **Write** `config/services/create_restaurant_offer.yaml`
8. **Update** `app/main.py` — swap all references
9. **Update** `app/shared/middleware/auth.py` — add new auth verifier
10. **Delete** old `app/services/create_menu_image/` folder
11. **Delete** old `config/services/create_menu_image.yaml`

---

## Out of Scope (not in this change)

- Database or persistent storage changes
- Frontend changes
- Translation service
- Any other existing service

---

## Example API Request (new format)

```json
POST /restaurant-offer/create
Authorization: Bearer <token>

{
  "zId": "restaurant123",
  "occasion": "Valentine's Day",
  "offerItems": "Beef Carpaccio 12.90\nRisotto ai Funghi 18.50\nChocolate Fondant 9.90\nProsecco 7.50\nRose Petal Cocktail 11.00",
  "logoImageUrl": "https://example.com/logo.png",
  "visualPrompt": "Romantic dark atmosphere, candles, deep red roses, elegant gold accents"
}
```

---

## Example API Request (daily special)

```json
{
  "zId": "taverna_bg",
  "occasion": "Daily Special",
  "offerItems": "Tomato Soup 4.50\nGrilled Chicken with Roasted Vegetables 13.90\nHouse Wine (glass) 4.00\nSparkling Water 2.50",
  "logoImageUrl": "https://example.com/logo.png",
  "visualPrompt": "Clean, modern, fresh. Bright and appetizing."
}
```
