# Naujawan Marketing OS — Data & JSON guide

Copy this file into **Claude** when you want it to generate importable packs. The live app mirrors the same rules in **Schema**.

---

## What the app stores

| Layer | Where you enter it | What it’s for |
|--------|--------------------|---------------|
| **Brief campaign** | Sidebar → **New Campaign** → **Quick** | Name + description; 60-day default range; tiny auto “Deck” HTML. |
| **Full campaign JSON** | **New Campaign** → **Import JSON** | Large timeline: `events[]`, optional full `html` deck, metadata. |
| **Team note (plain text)** | Calendar → day cell → **Team notes** | One string per `YYYY-MM-DD`. |
| **Shot day pack (JSON object)** | Calendar → day cell → **Shot day pack** | One **object** per date: call sheet, rundown, crew, scenes—your shape. |
| **Day notes + shot packs** | Firestore `workspace/dayNotes` + `workspace/dayShotDays` (or `localStorage` offline) | Synced maps keyed by ISO date strings. |

---

## 1 — Quick campaign (no JSON path)

Minimal fields entered in the UI. The app assigns:

- `id`: `slug-from-name-{timestamp}`
- `start`: today (`YYYY-MM-DD`)
- `end`: today + 60 days
- `events`: `[]`
- `html`: auto-generated briefing page from name + description

---

## 2 — Campaign JSON (Import JSON modal)

Root value must be a **single JSON object** (`{}`). **Arrays at the root are invalid.**

### Required

- **`name`** (string) — human title.

### Highly recommended

- **`events`** (array) — each item needs:
  - **`date`** — `YYYY-MM-DD`
  - **`type`** — see [Event types](#event-types)

Optional per event:

- **`title`** (string)
- **`note`** (string)
- **`pin`** (number) — used in Plan UI hints

### Optional top-level fields

| Field | Type | Notes |
|-------|------|------|
| `description` | string | Long briefing; fills cards + generated deck when no `html`. |
| `tagline` | string | Short subtitle; shown if description empty. |
| `status` | string | `"planning"` \| `"active"` \| `"complete"` (default `active`). |
| `accent` | string | Hex, e.g. `"#c8102e"` for UI tint. |
| `start` | string | `YYYY-MM-DD`; if omitted, derived from earliest event or defaults to today. |
| `end` | string | `YYYY-MM-DD`; if omitted, derived from latest event or start + 60 days. |
| `html` | string | Full HTML document for iframe “Deck”. If omitted, a briefing HTML is generated. |
| `importedAt` | string | ISO timestamp; overwritten on import if you omit it. |

### `id` field

You may omit **`id`**. The app **always assigns** a fresh id `{slug}-{timestamp}` so imports never collide with existing campaigns. To reference a slug in tooling, encode it in **`name`** or **`description`** instead.

### Example (focused)

```json
{
  "name": "May 2026 — Identity month",
  "description": "Five hero drops + supporting B-tier cadence.",
  "status": "active",
  "accent": "#c8102e",
  "start": "2026-05-01",
  "end": "2026-06-15",
  "events": [
    {
      "date": "2026-05-08",
      "type": "shoot",
      "title": "Shoot — batch 1",
      "note": "A-tier block + B-tier seed"
    },
    {
      "date": "2026-05-14",
      "type": "a-tier",
      "title": "Brand intro hero",
      "note": "Pin immediately",
      "pin": 1
    }
  ]
}
```

### Example with custom `html`

If `html` is present and non-empty, it becomes the iframe source. Useful when Claude outputs a styled deck.

```json
{
  "name": "June drop",
  "events": [{ "date": "2026-06-01", "type": "drop", "title": "Merch live" }],
  "html": "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>June</title></head><body><h1>June</h1></body></html>"
}
```

### Validation quirks

- Invalid `events[].date` rows are **skipped** (warning in browser console).
- Malformed JSON shows an inline error in the modal before import.

---

## 3 — Shot day JSON (per calendar cell)

Triggered from **Master Calendar** → click a date → **Shot day pack (JSON)**.

Rules:

1. Exactly **one JSON object** per day — not an array at root.
2. Paste into the textarea, or **Load .json file**.
3. **Save shot day** writes to storage; **Clear** removes the object for that date.

### Recommended shape (all keys optional — adapt to production)

Your team can evolve this freely; suggested fields:

```json
{
  "label": "Shoot day 03 — pickups",
  "callTime": "06:30",
  "wrap": "20:00",
  "timezone": "America/Los_Angeles",
  "location": "Stage A — Blackwood",
  "address": "123 Example Rd",
  "parkingNotes": "Crew entrance on east side",
  "talent": [
    { "name": "", "slots": ["08:30–11:00"] }
  ],
  "crewHeads": { "Director": "", "Photo": "", "HMU": "" },
  "scenes": [
    { "id": "S05", "description": "Table hero + inserts", "estBlocks": ["08:00–12:30", "14:00–17:30"] }
  ],
  "equipmentCritical": ["LUXE body", "Sirui slider"],
  "cateringNotes": "",
  "refs": ["https://docs.google.com/…"],
  "notes": "Any free prose not covered elsewhere."
}
```

Calendar cells show a **gold dot** when a shot pack exists.

---

## 4 — Legacy HTML decks (still supported in JSON)

Older workflows embed meta + timeline inside HTML (`naujawan:*` metas + `application/naujawan-events` script). The **recommended** flow now is standalone **campaign JSON**. If Claude outputs HTML, put the raw document string into the **`html`** field and optionally duplicate events in **`events[]`** so the planner and calendar stay in sync without HTML parsing.

---

## Event types

| `type` | Meaning |
|--------|---------|
| `a-tier` | Hero films — pin-worthy |
| `b-tier` | Daily feed rhythm |
| `shoot` | Production day |
| `drop` | Product / merch alive |
| `story` | Ephemeral stories |
| `task` | Prep / logistics |
| `note` | Milestones that are not posts |

---

## Persistence & Firestore

| Path | Contents |
|------|-----------|
| `campaigns/{id}` | Serialized campaign minus `id` (includes `events`, optional `description`, optional `html`, …). |
| `workspace/dayNotes` | `dates["YYYY-MM-DD"]` → plain string note. |
| `workspace/dayShotDays` | `dates["YYYY-MM-DD"]` → arbitrary map (your shot JSON). |

Local-only mode mirrors the same keys in `localStorage`.

---

## Checklists

**Campaign JSON**

- [ ] Root is `{}`, not `[…]`.
- [ ] `name` is set.
- [ ] Each event has ISO `date` + `type`.
- [ ] `html` escapes quotes if embedded as a JSON string.

**Shot day JSON**

- [ ] Root is `{}`.
- [ ] File saved as `.json`, UTF-8.

---

## Import steps (operators)

1. **New Campaign** → **Quick** → type name/description → Create.  
   _or_
2. **New Campaign** → **Import JSON** → paste Claude output or Load `.json` → Import campaign.  
3. **Calendar** → open a shoot date → paste / load shot JSON → Save shot day.

Done.
