# VOTD — Admin Tool

Reference for the editorial admin dashboard. Covers role model, environments, open questions, and decisions outstanding from the build sessions.

---

## Role model — three phases

| Role | Phase | Can see Prototype | Can see Live | Jurisdiction restriction |
|---|---|---|---|---|
| `superuser` | 1, 2, 3 | Yes | Yes | None |
| `editor` | 1 | Yes | Yes | None |
| `editor_live` | 2 | No | Yes | None |
| `editor_proto` | 2 | Yes | No | None |
| `editor_regional` | 3 | No | Yes | `allowed_jurisdiction_ids` only |

**Phase 1 (now):** Small team, everyone is `editor` or `superuser`, full access to both environments.
**Phase 2 (live launch):** Editors split by environment — some manage prototype, some manage live.
**Phase 3 (multi-jurisdiction):** Regional editors see only their assigned county/city queues.

The `allowed_jurisdiction_ids` column on `admin_users` is already in the schema — it stays `NULL` for unrestricted roles and gets populated for `editor_regional` accounts in Phase 3.

---

## Environments

Two completely separate Supabase projects — not schemas within the same project. A mistake in the admin prototype view can never touch live data. The admin dashboard switches between them via different API keys in environment variables.

**My Queue** spans both environments — an editor's personal inbox of all assigned items regardless of which environment they're working in.

---

## Queue structure

Three primary queues: **Proposals**, **Votes**, **Citizens**.

Editorial and Flags were removed when the three-queue structure was adopted. If volume grows, Flags may return as a sub-view within one of the three primary queues.

### Item states (proposals)

| Status | Meaning |
|---|---|
| `pending` | Submitted, not yet reviewed |
| `approved` | Published |
| `returned` | Sent back to submitter for revision |
| `rejected` | Declined |

### Workflow indicators (on top of status)

| Indicator | Meaning |
|---|---|
| Yellow dot on Pending | Opened by an editor but not yet actioned |
| Assignee shown | An editor is tagged as responsible |

### Editor actions

- **Approve** — accept as-is
- **Approve with edits** — modify title/question/topic before publishing
- **Return for revision** — send back to submitter with notes (proposals only)
- **Reject** — decline with reason code

Editors action the whole item — they do not override individual signals. A flagged item can still be approved; signals are informational only.

---

## Open questions

### Auth & Login

1. **Password reset flow** — Email-based reset works via `/auth/callback`. Do we want a "Set password" UI inside the admin itself, rather than relying on Supabase dashboard or SQL?
2. **Magic link as primary login** — Given password auth has been unreliable to set up, should magic link be the primary login method with password as optional? Or enforce password + MFA for all editors once the team grows?
3. **MFA enforcement** — MFA is built in but not currently required. At what point should it become mandatory — all editors, or only live environment actions?

### Signals & Editorial Workflow

4. **Editorial queue scope** — ✅ ANSWERED: The Editorial Queue is the landing zone for the automated sourcing pipeline (Claude-sourced draft votes). It is distinct from Proposals (user-submitted ideas). See `docs/vote-sourcing-workflow.md` for full spec. `EditorialQueue.tsx` stub to be routed at `/:env/editorial` and added to the sidebar between Proposals and Votes.
5. **Social queue** — "Social" was a stub in the old sidebar. Social media listening feed (flagged posts about active votes), or something else? In scope for pilot?
6. **Flag actioning** — Should there be a free-text notes field when returning or rejecting a proposal so the submitter gets a reason? Is that reason visible to the submitter in the mobile app?
7. **Anomaly resolution** — When an anomaly is resolved (e.g. bot_suspect turns out to be legitimate), what happens to the suppressed votes — reinstated or permanently excluded?

### Votes Master

8. **Vote close dates** — Who sets the close date? Editor at approval time, the proposal itself, or jurisdiction rules?
9. **Per-vote vs per-voter view** — The Votes queue shows one row per vote topic. Do we need a drill-down to individual vote records, or is that handled via Citizens?
10. **Weighted vs raw results** — Should the weighted (trust-adjusted) result be the "official" result surfaced publicly, or internal-only for now?

### Citizens

11. **Citizen-to-proposal linking** — Should the submitter username on a proposal row be a clickable link to their Citizens profile?
12. **Verified voter flow** — Address check against voter registration hasn't been designed yet. What data does a citizen need to provide, and is it in scope for the pilot?

### Navigation & Structure

13. **My Queue in Live** — My Queue currently spans both Prototype and Live. Should Live items be more strongly distinguished (e.g. red/green border) given the higher stakes?

### Jurisdictions

14. **Jurisdiction setup** — Jurisdictions page is a stub. For the Sacramento pilot: City Council, County Board, School District, others? Who manages jurisdiction records — superuser only, or any editor?

### Deployment

15. **Vercel deployment** — Admin is currently running locally only. When does it need a real URL? Shared deployment or separate Prototype vs Live?

---

## Next steps (backend wiring)

1. Seed `jurisdictions` table with Sacramento civic bodies from mockData
2. Replace mock auth with Supabase Auth + TOTP MFA enforcement
3. Add Supabase JS client to `apps/admin`
4. Wire admin queue pages to real Supabase queries
5. Add invite flow for new admin users (superuser → email invite → TOTP enroll)
