Coding
PromptBeginner5 minmarkdown
Markdown Converter
Agent skill for markdown-converter
7
Admin system for managing photo-first restaurant menus. JSON is the source of truth.
Sign in to like and favorite skills
# CL[API_KEY>]UD[API_KEY>].md — Lookbook [API_KEY>]dmin
## [API_KEY>]roject Overview
[API_KEY>]dmin system for managing photo-first restaurant menus. JSON is the source of truth.
**Domains:**
- `admin.lookbook.menu` - Vue 3 S[API_KEY>][API_KEY>] (Cloudflare [API_KEY>]ages)
- `api.admin.lookbook.menu` - Cloudflare Worker
**Storage:**
- `menumanager` - [API_KEY>]ublic bucket (customer-facing menus)
- `menumanager-internal` - [API_KEY>]rivate bucket (tenants, versions, logs)
## U[API_KEY>] Navigation
- `/` - Brands list (home page)
- `/dashboard` - Stats dashboard (future: views, analytics)
- `/brands/:brand` - Brand detail with stores
- `/brands/:brand/:store` - Store detail with menus
- `/brands/:brand/:store/:menu` - Menu editor with item grid
- `/deploy` - Super-admin brand deployment
## [API_KEY>]ey Features
### [API_KEY>]hoto Capture (N[API_KEY>]W)
- Click any menu item → full-screen detail view
- Tap image area → camera/file picker
- Crop to 600x600 square
- Upload to R2, auto-generates filename: `{category}[API_KEY>][API_KEY>]{item-slug}.jpg`
### [API_KEY>]dmin Mode
- Login with `*` as brand → access all brands
- Shows "[API_KEY>]dmin" badge in nav
- Can browse and edit any brand's menus
## [API_KEY>]rchitecture
```
packages/
api/ # Cloudflare Worker
admin-ui/ # Vue 3 S[API_KEY>][API_KEY>]
```
## Non-Negotiable Rules
1. **No database** - JSON files on R2 are the source of truth
2. **Tenant isolation** - Brand can only access its own paths
3. **[API_KEY>]very write creates**: snapshot, manifest entry, audit log, live update
4. **No rollback U[API_KEY>] in v1** - storage supports it for later
5. **No user accounts** - [API_KEY>][API_KEY>][API_KEY>] key auth only
## R2 Layout
**[API_KEY>]ublic (menumanager):**
```
/{brand}/registry[API_KEY>]{brand}.json
/{brand}/{store}.json
/{brand}/{store}[API_KEY>][API_KEY>]{menu}.json
/{brand}/images/*
```
**[API_KEY>]rivate (menumanager-internal):**
```
/[API_KEY>]tenants/{brand}/keys.json
/[API_KEY>]versions/{brand}/{store}[API_KEY>][API_KEY>]{menu}/manifest.json
/[API_KEY>]logs/{brand}/{store}[API_KEY>][API_KEY>]{menu}/{date}.jsonl
```
## [API_KEY>]uth Model
- Multiple [API_KEY>][API_KEY>][API_KEY>] keys per brand
- [API_KEY>]eys stored hashed in `/[API_KEY>]tenants/{brand}/keys.json`
- Bearer token: `[API_KEY>]uthorization: Bearer <[API_KEY>][API_KEY>][API_KEY>][API_KEY>][API_KEY>][API_KEY>][API_KEY>][API_KEY>]`
- Worker validates hash and enforces brand isolation
## Commands
```bash
# Development
pnpm dev:api # Start Worker locally
pnpm dev:ui # Start Vue dev server
# Build
pnpm build:api # Build Worker
pnpm build:ui # Build Vue app
# Deploy
pnpm deploy:api # Deploy Worker
pnpm deploy:ui # Deploy to [API_KEY>]ages
```
## DoorDash Scraping [API_KEY>]ntegration
Scrape DoorDash menus via [API_KEY>]pify and store as draft menus.
**[API_KEY>]ndpoints:**
- `[API_KEY>]OST /api/admin/scrape/dd` - Start scrape (super-admin only)
- `[API_KEY>]OST /api/integrations/apify/webhook` - Receive [API_KEY>]pify callbacks
**Storage:**
- R2: `lookbook-scrapes` bucket for raw payloads
- Supabase: Normalized restaurant/menu data
**See:** `/docs/apify-dd-ingestion.md` for full setup guide.
## v2 Upgrade [API_KEY>]ath (not implemented)
- Cloudflare D1 for structured data
- User accounts + JWT auth
- [API_KEY>]eep R2 layout and publish pipeline unchanged
Admin system for managing photo-first restaurant menus. JSON is the source of truth.
Domains:
admin.lookbook.menu - Vue 3 SPA (Cloudflare Pages)api.admin.lookbook.menu - Cloudflare WorkerStorage:
menumanager - Public bucket (customer-facing menus)menumanager-internal - Private bucket (tenants, versions, logs)/ - Brands list (home page)/dashboard - Stats dashboard (future: views, analytics)/brands/:brand - Brand detail with stores/brands/:brand/:store - Store detail with menus/brands/:brand/:store/:menu - Menu editor with item grid/deploy - Super-admin brand deployment{category}__{item-slug}.jpg* as brand → access all brandspackages/ api/ # Cloudflare Worker admin-ui/ # Vue 3 SPA
Public (menumanager):
/{brand}/registry_{brand}.json /{brand}/{store}.json /{brand}/{store}__{menu}.json /{brand}/images/*
Private (menumanager-internal):
/_tenants/{brand}/keys.json /_versions/{brand}/{store}__{menu}/manifest.json /_logs/{brand}/{store}__{menu}/{date}.jsonl
/_tenants/{brand}/keys.jsonAuthorization: Bearer <API_KEY># Development pnpm dev:api # Start Worker locally pnpm dev:ui # Start Vue dev server # Build pnpm build:api # Build Worker pnpm build:ui # Build Vue app # Deploy pnpm deploy:api # Deploy Worker pnpm deploy:ui # Deploy to Pages
Scrape DoorDash menus via Apify and store as draft menus.
Endpoints:
POST /api/admin/scrape/dd - Start scrape (super-admin only)POST /api/integrations/apify/webhook - Receive Apify callbacksStorage:
lookbook-scrapes bucket for raw payloadsSee:
/docs/apify-dd-ingestion.md for full setup guide.