{
  "summary": "Iter-8 backend regression PASS (77/77) + frontend smoke. Updated test_offislux.py: bumped niche count 26→27, allowed empty meta_ad_account_id (Meta API stays mocked per .env). Added 7 new iter-8 tests across 3 classes: TestNichesOther (4) — verifies GET /api/niches?lang=en returns 27 items with {id:'other', name:'Other Local Business', category:'Other'}; lang=pt returns 'Outro / Personalizado'/'Outro'; lang=fr returns 'Autre / Personnalisé'; GET /api/niches/other returns 4 scripts + 3 generic local-business headlines. TestCreateCampaignOtherNiche (1) — POST /api/campaigns with niche_id='other' (no lang param, no profile country) succeeds and persists niche_name='Other Local Business' on the Mongo doc. TestShotstackUrlHelperProductionV1 (2) — direct import of server._shotstack_url with SHOTSTACK_ENV='v1' returns 'https://api.shotstack.io/v1/render' (and base/no-path variants); .env file contains SHOTSTACK_ENV=\"v1\". FRONTEND smoke at https://meta-ads-easy.preview.emergentagent.com: Landing → 27 niche-card-* tiles render; niche-card-other present (last tile, category 'Other', 'Other Local Business'); EVERY card carries the EN clipsHint subtext 'Film/photo · 1–8 clips · 30–60s ad' (PT translation 'Filme/foto · 1–8 clipes · anúncio 30–60s' wired in i18n.js — verified via source). CampaignDetail (newly-signed-up user, profile empty) → SERVICE AREA section renders with 'No address yet — add one to see the radius on the map · 20km' fallback; edit-address-btn opens the inline address-edit-form with 3 inputs (addr-edit-address, addr-edit-city, addr-edit-country) + Cancel/Save. **BUG: clicking Save fires PUT /api/profile but receives 422 because BusinessProfileIn requires business_name + nif + address + city, and the new user has no prior profile to spread from. The frontend toast shows 'Failed' and the form stays open. URL did not redirect (good — page stayed on /dashboard/campaigns/{id}).** Map still updates because the form state holds the new values, but persistence is broken for users without a pre-existing profile.",
  "backend_issues": {"critical": [], "minor": []},
  "frontend_issues": {
    "ui_bugs": [
      {"component": "CampaignDetail.saveAddr", "issue": "PUT /api/profile returns 422 when user has no prior profile — saveAddr spreads {...profile, ...addrDraft} but profile is null/empty, so business_name + nif (required by backend BusinessProfileIn) are missing. Save shows 'Failed' toast; form stays open; address is NOT persisted. The address only persists for users who already completed profile (e.g. via Onboarding).", "selector": "[data-testid='addr-save']", "priority": "HIGH"}
    ],
    "integration_issues": [
      {"flow": "Inline address edit from CampaignDetail (no-prior-profile path)", "issue": "PUT /api/profile 422 — schema mismatch. Either (a) make BusinessProfileIn fields optional / add a partial-update endpoint, or (b) have saveAddr send sensible defaults (business_name from auth user, nif='') so first-time save succeeds.", "affected_selectors": ["[data-testid='addr-save']", "[data-testid='address-edit-form']"]}
    ],
    "design_issues": []
  },
  "critical_code_review_comments": [
    "frontend/src/pages/dashboard/CampaignDetail.jsx:145-153 — saveAddr does `api.put('/profile', { ...profile, ...addrDraft })`. When profile is null (new user) only address/city/country are sent and the backend (BusinessProfileIn requires business_name + nif) returns 422. Recommended fix: in saveAddr, default missing required fields, e.g. `{ business_name: profile?.business_name || user?.name || user?.email?.split('@')[0] || 'My Business', nif: profile?.nif || '', address: '', city: '', country: 'Portugal', ...profile, ...addrDraft }`. OR add a backend PATCH /api/profile/address that accepts only the 3 fields.",
    "backend/.env:17-18 — META_MASTER_AD_ACCOUNT_ID and META_LONG_LIVED_TOKEN are intentionally empty; campaign docs now persist meta_ad_account_id=''. The TestCampaignPageIdentityAndBudget legacy assert that required a truthy value was relaxed (allowed '' or 'act_MASTER_MOCK' fallback). When the master account creds land, restore the strict assert.",
    "backend/server.py:477-479 — _shotstack_url reads SHOTSTACK_ENV at call-time (good — supports per-test override). Live env uses 'v1' so /render hits production https://api.shotstack.io/v1/render."
  ],
  "test_report_links": [
    "/app/backend/tests/test_offislux.py",
    "/app/test_reports/pytest/pytest_results.xml"
  ],
  "action_items": [
    "Fix CampaignDetail.saveAddr so first-time profile save (no prior profile row) doesn't 422 — provide defaults for business_name + nif, or add a backend partial-profile endpoint.",
    "When META_MASTER_AD_ACCOUNT_ID + META_LONG_LIVED_TOKEN are populated, swap the campaign-creation MOCK call for the real Meta Marketing API path AND tighten TestCampaignPageIdentityAndBudget to require c['meta_ad_account_id'].startswith('act_')."
  ],
  "updated_files": [
    "/app/backend/tests/test_offislux.py",
    "/app/test_reports/iteration_8.json",
    "/app/test_reports/pytest/pytest_results.xml"
  ],
  "success_rate": {"backend": "100% (77/77)", "frontend": "Partial — Landing niches grid + 'other' card + clipsHint subtext + CampaignDetail geofence-section + edit-address-btn + inline address-edit-form (3 inputs) all render correctly. Save flow blocks on 422 PUT /api/profile when user has no prior profile — see ui_bugs."},
  "test_credentials": "admin@offislux.com / Admin@2026; signup creates TEST_<hex>@offislux.com with Test@2026",
  "seed_data_creation": "Pytest creates per-class TEST_ users + campaigns; iter-8 frontend test created TEST_<hex>@offislux.com via signup and one restaurant campaign on the live preview URL.",
  "retest_needed": true,
  "main_agent_can_self_test": true,
  "context_for_next_testing_agent": "Iter-8 added 7 tests at /app/backend/tests/test_offislux.py (TestNichesOther×4, TestCreateCampaignOtherNiche×1, TestShotstackUrlHelperProductionV1×2). The single iter-8 frontend bug is in CampaignDetail.saveAddr — backend BusinessProfileIn requires business_name + nif so a fresh user (profile null) gets 422 on PUT /api/profile. Suggested fix is in critical_code_review_comments. Run pytest with `set -a && source /app/backend/.env && set +a && pytest backend/tests/test_offislux.py` because REACT_APP_BACKEND_URL/MONGO_URL must be in env. SHOTSTACK_ENV is now 'v1' so the helper hits production Shotstack — render-video tests still accept 200 OR 502 on the Shotstack POST.",
  "rca of the issue": "frontend/src/pages/dashboard/CampaignDetail.jsx saveAddr() builds the PUT body via spread of (possibly-empty) profile + addrDraft. Backend BusinessProfileIn requires {business_name, nif, address, city} → 422 when those are missing. Reproduce: 1) sign up new user, 2) /dashboard/campaigns/{cid}, 3) click edit-address-btn, 4) fill 3 inputs, 5) Save → toast 'Failed', form stays open, console shows 422 on /api/profile. Mitigation: defaults in saveAddr OR backend partial-profile endpoint."
}
