Skip to content
prod e051e98
Browse

1 · Concepts & admin model

Objective — set the vocabulary and the two failure modes (wrong tier, wrong Livewire form) before touching a form, so every later page in this phase can assume them.

This phase configures the vendor’s existing admin panel — branding, payments, email, plans, legal pages — as the logged-in superadmin. You write almost no code; you inspect what the panel exposes and fill it in. Read this page once: it sets the vocabulary and the two failure modes (wrong tier, wrong Livewire form) that every later page assumes you’ve internalized.

1. Separate the two meanings of “admin”

Section titled “1. Separate the two meanings of “admin””

The word admin refers to two different things in this playbook — different places, different lifecycles. Internalize which one this phase operates in before going further.

  1. Distinguish the in-app superadmin from the ops admin tiers.
    • The in-app superadmin is the account you log into the running app with to set branding, payments, email, and pages. That is this phase. Its config persists into the app’s database and .env.

    • The ops admin tiers are the on-disk folders where project guides, secrets, deploy logs, and shared monitoring scripts live. They surround the app but are never edited from the panel.

    • ✅ You can state which sense each task in this phase operates in (the panel), and why the second sense still matters (the secrets you paste — SMTP, Stripe — and the deploy webhooks resolve through those tiers).

The ops side follows a three-tier model. You don’t change it in Phase 6 — but knowing which tier a path belongs to is what keeps “rotate a webhook” from meaning “edit N projects.”

flowchart TD
subgraph LOCAL["Admin-Local · in git (vault gitignored)"]
direction LR
L1["Phase guides + ProjectCard"]
L2["Project vault — secrets"]
L3["Customizations registry"]
end
subgraph SERVER["Admin-Server · own repo · server-wide"]
direction LR
S1["server.env — shared webhooks"]
S2["Monitoring + MD5 baselines"]
end
subgraph DOMAIN["Admin-Domain · never in git · per-domain runtime"]
direction LR
D1["Deploy history log"]
D2["Per-domain backups + crons"]
end
LOCAL -->|"authoring → deploy"| DOMAIN
SERVER -->|"shared config inherited by every domain"| DOMAIN
  1. Map each path to its tier.

    TierLives atScopeIn git?
    Admin-Localthe project repo (Admin-Local/)this one codebaseYes — except the secrets vault (2-ProjectVault/)
    Admin-Domainthe server, per domain (~/domains/<domain>/Admin-Domain/)one staging/prod domainNo — pure runtime state
    Admin-Serverthe server, once per account (~/Admin-Server/)every domain on the hostYes — its own repo

    Mnemonic: Local → your laptop’s project folder. Domain → on the server, scoped to one domain. Server → on the server, scoped to the whole hosting account.

    • ✅ Given any ops path, you can name its tier without guessing.

One naming detail trips up agents reading older guides — fix it on sight:

The admin panel differs per app, so don’t follow a fixed checklist — inspect, then configure what exists. Every task in this phase is the same shape: CHECK the panel → configure if present → defer to a later phase’s full guide if absent. Never assume a label.

flowchart TD
Start["Generic task<br/>(e.g. 'configure SMTP')"] --> Check{"Does the panel<br/>expose it?"}
Check -->|Yes| Conf["Configure in-panel now<br/>(≈5-min task)"]
Check -->|No| Defer["Defer to the linked<br/>full guide (later phase)"]
Conf --> Verify["Verify it persisted<br/>(hard reload / curl)"]
Defer --> Log["Log the decision<br/>in _CUSTOMIZATIONS.md"]
Verify --> Log
  1. Map the panel read-only first. Log in and walk every nav item, settings tab, and profile menu without changing anything. Record the structure (URL + label of each setting) in _CUSTOMIZATIONS.md. This map makes a later re-run — e.g. on a fresh production DB — dramatically faster.

    • _CUSTOMIZATIONS.md holds a URL + label for each setting, with nothing changed.
  2. For each task: CHECK → configure or defer. If the app exposes the setting, configure it now. If it doesn’t, defer to the linked full guide in a later phase.

    • ✅ Each task is resolved as configured-now or deferred-with-link, never silently skipped.
  3. Capture capabilities once. A single up-front survey (the next page) of what’s admin-editable vs hardcoded, which modules ship, and which features are tier-gated keeps every later step from deciding in ignorance.

    • ✅ The survey from the next page is treated as the input to every later “CHECK”.

4. Plan an AI-assisted inspection pass (Playwright)

Section titled “4. Plan an AI-assisted inspection pass (Playwright)”

If the Playwright MCP is available, the agent can inspect the panel automatically instead of you browsing manually. The map is the input to every later “CHECK” — it converts “where is this setting?” from manual hunting into automated discovery.

  1. Run a read-only mapping pass first. Have the agent log in, then walk every sidebar item, settings tab, and profile menu — taking snapshots and extracting the URL + label of each. No configuration changes during this pass.

    • ✅ A snapshot + URL + label is captured for every nav surface, with nothing changed.
  2. Summarize the structure. Sidebar items, settings tabs, profile menu, and any dashboard-level nags (an “SMTP not configured” banner is a validation signal that the email page needs work).

    • ✅ The summary names every settings tab and any dashboard nag.
  3. Save the map to _CUSTOMIZATIONS.md as an “Admin panel structure” section, and screenshot the key config pages.

    • ✅ The map and screenshots are persisted to _CUSTOMIZATIONS.md.
  4. Propose an ordered plan from what’s actually present — skip tasks for features the app lacks, promote any dashboard nags to the top.

    • ✅ The plan reflects only present features, with nags promoted.

This is optional — every task can be done by browsing manually. But on a typical Froiden/WorkDo/SocietyPro-style app, a 5-minute map pass saves ~30 minutes of back-and-forth later.

5. Read the Livewire component before you click “Save”

Section titled “5. Read the Livewire component before you click “Save””

CodeCanyon admin pages often host 3–6 independent Livewire forms on a single page (a Disable-Landing toggle, an FAQ editor, a Contact form, a Footer editor, an SEO editor). Driving them blindly — by Playwright or by hand — is the single most common Phase 6 time-sink. Three traps stack:

TrapWhat goes wrong
Multiple forms per pageA generic wire:target="submitForm" button hits whichever form matches the selector — not the one whose fields you just filled.
Non-convention method namesVendors use saveContact, updateBranding, uploadLogo instead of submitForm/save. Grepping for submitForm misses them all.
Scoped recordsRecords filtered by language_setting_id, society_id/tenant_id, user_id, or guard. Save without the scope value and Livewire writes an orphan row or updates a different record than the one on screen.

The 30-second pre-flight below — run it BEFORE every form interaction — spends 30 seconds reading the component source to prevent a 15-minute “why didn’t the save work?” loop.

  1. Find the Livewire component(s) the page renders.

    Terminal window
    grep -rn "Livewire::" resources/views/ --include="*.blade.php" 2>/dev/null \
    | grep -iE "landing|contact|setting|branding|payment" | head -10
    # Expected: the blade lines that mount the page's Livewire components
    • ✅ You have the component name(s) the page mounts.
  2. Find every submit method (not just submitForm).

    Terminal window
    grep -rnE "public function (save|submit|update|store|upload)[A-Za-z]*\s*\(" \
    app/Livewire/ --include="*.php" 2>/dev/null | head -20
    # Expected: the real save-method names (e.g. saveContact, updateBranding)
    • ✅ The actual save method for your page is identified — not assumed to be submitForm.
  3. Read the component class for YOUR page, noting the save method, the $rules (conditional validation), the scope fields, and mount(). Then find the table it writes to.

    Terminal window
    grep -n "protected \$table\|Model::" app/Models/[ModelName].php 2>/dev/null
    # Expected: the $table name (or Model:: usage) the component persists to
    • ✅ Save method, conditional rules, scope fields, and target table are all known before any save.

Rule of thumb: when a Playwright save doesn’t persist, don’t troubleshoot Livewire sync or caching first — grep the component source. 80% of the time the bug is the guide’s assumption about method name, form identity, or scope, not Livewire itself.

Do not mark this step done until every box below is checked.

  • 🤖 Two meanings clear — both senses of “admin” are clear; the three ops tiers are understood (you can name which tier a path belongs to).
  • 🤖 Check-first internalized — CHECK → configure-or-defer → verify → log.
  • 🤖 Map pass planned — if using Playwright, a read-only map pass is planned before any change.
  • 🤖 Livewire pre-flight understood — the 30-second component check is understood before touching any form.