Cursor User Onboarding Implementation Plan: Difference between revisions
Created page with "This page details how the user onboarding experience was configured." |
Cursor: publish user onboarding implementation plan |
||
| Line 1: | Line 1: | ||
This page | Implementation plan for the enhanced user onboarding experience. Requirements source: [[New User Onboarding]]. | ||
'''Scope for this plan:''' two environment choices only — '''Default wiki''' and '''Demo preload'''. PARA wiki is deferred. User-info enhancements (signup audit, name/avatar sync, timezone) are a separate track. | |||
Synced from git <code>docs/wikifam_community_roadmap.md</code> §1 and Cursor planning session (September 2026). | |||
== Goals == | |||
{| class="wikitable" | |||
! Goal !! Success criteria | |||
|- | |||
| '''Choice''' || New user picks '''Default wiki''' or '''Demo preload''' before provisioning | |||
|- | |||
| '''Demo preload''' || User sees demo Main Page hierarchy with '''Page''' + '''Contents''' checkboxes (all checked by default) | |||
|- | |||
| '''Granular import''' || Both checked → full page; Page only → first sentence + back-link; neither → page omitted | |||
|- | |||
| '''Default wiki''' || Stock MediaWiki install, no demo import | |||
|- | |||
| '''Reliability''' || Provisioning job carries selections; worker applies them deterministically | |||
|} | |||
'''Out of scope (this plan):''' PARA wiki path, Areas/Topics/Projects picker, filtered import driven by PARA selections. | |||
'''Deferred (same requirements page, separate track):''' signup audit logging (IP/geo/browser), <code>wiki_registry</code> name/avatar fields, <code>wiki_member_name_changes</code>, timezone default from Google at registration. | |||
== Current state == | |||
Today the flow is: Google login → slug on <code>goalstriving.org/get-started.php</code> → async job → <code>create-wiki.sh</code> → '''full''' <code>demo-template.xml</code> import for every personal wiki. | |||
* No environment choice | |||
* No page checklist | |||
* Job JSON has no <code>environment</code> or <code>template_selection</code> | |||
* <code>import-wiki-template.sh</code> only supports full XML dump import | |||
'''Key repo files today:''' | |||
{| class="wikitable" | |||
! Area !! Path !! Role | |||
|- | |||
| Portal UI || <code>portal/public/get-started.php</code> || Slug form + job polling only | |||
|- | |||
| Jobs || <code>portal/lib/jobs.php</code> || Async provision job JSON | |||
|- | |||
| Worker || <code>portal/bin/provision-wiki.php</code> || Calls <code>create-wiki.sh</code> | |||
|- | |||
| Provision || <code>scripts/create-wiki.sh</code> || DB + MW install + full template import | |||
|- | |||
| Import || <code>scripts/import-wiki-template.sh</code> || Full XML + uploads rsync | |||
|- | |||
| Template export || <code>scripts/export-demo-template.sh</code> || Golden export from demo wiki | |||
|- | |||
| Registry || <code>sql/auth-schema.sql</code> || <code>wiki_members</code>, invites, audit | |||
|} | |||
== Target user experience == | |||
Multi-step wizard on <code>goalstriving.org/get-started.php</code> (session-backed; CSRF on each POST): | |||
'''Step 1 — Environment''' | |||
* ○ Default wiki (MediaWiki starter pages only) | |||
* ● Demo preload (recommended) — outline + optional sample content | |||
* ○ PARA wiki — ''disabled/greyed: “Coming in a future release”'' with link to [[New User Onboarding]] | |||
'''Step 2 — Wiki address''' | |||
* <code>[slug].goalstriving.org</code> (existing validation) | |||
'''Step 3 — Page checklist''' (only if Demo preload) | |||
* Hierarchical tree from demo Main Page | |||
* Columns: '''Page''' ✓ and '''Contents''' ✓ (both default ON) | |||
* Select all / Clear all + section expand/collapse | |||
'''Step 4 — Review & create''' | |||
* Summary → submit → existing job polling UI | |||
=== Checkbox semantics === | |||
Per [[New User Onboarding#Setup for Standard wiki with static templates]]: | |||
{| class="wikitable" | |||
! Page !! Contents !! Result | |||
|- | |||
| ✓ || ✓ || Full demo revision for that title | |||
|- | |||
| ✓ || ✗ || Stub: first sentence only (same pattern as demo stubs) | |||
|- | |||
| ✗ || ✗ || Page not created; omitted from imported Main Page outline | |||
|} | |||
'''Always handled specially:''' | |||
* '''Main Page''' — Rebuilt after import to match selections (links only to pages that exist). Do not import demo Main Page verbatim then delete orphans. | |||
* '''Shared infrastructure''' — Confirm demo export has no required Form/Template pages after PARA removal from demo; if clean, selective main-namespace import is sufficient. | |||
== Architecture overview == | |||
<pre> | |||
Portal (wizard + manifest API) | |||
→ job JSON | |||
→ provision-wiki.php | |||
→ create-wiki.sh | |||
→ import-wiki-template.sh (default path / fallback) | |||
→ import-wiki-selection.php (NEW — selective import) | |||
</pre> | |||
== Demo page manifest == | |||
'''Problem:''' Wizard needs a stable tree independent of live demo edits during a deploy window. | |||
'''Solution:''' Generate <code>templates/demo-page-manifest.json</code> on each <code>export-demo-template.sh</code> run (server path: <code>/etc/goalstriving/templates/demo-page-manifest.json</code>). | |||
Example structure: | |||
<pre> | |||
{ | |||
"exported_at": "2026-09-04T21:39:14Z", | |||
"main_page_title": "Main Page", | |||
"pages": [ | |||
{ | |||
"title": "Personal", | |||
"parent": "Main Page", | |||
"depth": 1, | |||
"first_sentence": "This page contains notes about topics personal to me.", | |||
"has_sample_content": true | |||
} | |||
], | |||
"tree": { } | |||
} | |||
</pre> | |||
'''Generator:''' New script <code>scripts/build-demo-page-manifest.php</code>: | |||
# Read demo Main Page wikitext → parse <code>[[links]]</code> hierarchy | |||
# For each linked page in export XML, extract first sentence (text before first blank line / heading) | |||
# Write manifest alongside <code>demo-template.xml</code> | |||
# Optionally commit manifest to git for portal dev without EC2 | |||
'''Portal:''' <code>GET /api/demo-manifest.php</code> (authenticated) returns manifest JSON for wizard Step 3. | |||
== Job schema extension == | |||
Extend <code>startProvisioningJob()</code> in <code>portal/lib/jobs.php</code>: | |||
<pre> | |||
{ | |||
"type": "provision", | |||
"wiki_slug": "alice", | |||
"environment": "default | demo_preload", | |||
"template_selection": { | |||
"pages": { | |||
"Personal": { "page": true, "contents": true }, | |||
"Long-term goals": { "page": true, "contents": false }, | |||
"Biology 10": { "page": false, "contents": false } | |||
} | |||
} | |||
} | |||
</pre> | |||
* <code>environment: default</code> → ignore <code>template_selection</code>; skip template import entirely | |||
* <code>environment: demo_preload</code> → require <code>template_selection</code>; default all true if omitted (backward compat during rollout) | |||
Pass to worker: | |||
<pre> | |||
create-wiki.sh "$SLUG" "$SITE_NAME" "$ADMIN" \ | |||
--environment=demo_preload \ | |||
--selection-file=/tmp/job-{id}-selection.json | |||
</pre> | |||
== Backend: selective import == | |||
=== Phase A — Default wiki path (small) === | |||
<code>create-wiki.sh</code> changes: | |||
* Accept <code>--environment=default|demo_preload</code> | |||
* If <code>default</code>: skip <code>import-wiki-template.sh</code>; verify page count ≥ 1; lower or bypass <code>TEMPLATE_MIN_PAGES</code> check | |||
* Store <code>environment</code> in <code>wiki_registry</code> (new column <code>wiki_environment ENUM('default','demo_preload')</code> — migration in <code>sql/</code>) | |||
=== Phase B — Selective demo import (core) === | |||
Recommended: new <code>scripts/import-wiki-selection.php</code> (Maintenance runner): | |||
{| Step !! Action | |||
|- | |||
| 1 || Delete stock Main Page (existing behavior) | |||
|- | |||
| 2 || For each selected title with <code>contents: true</code>, import that page from XML | |||
|- | |||
| 3 || For <code>page: true, contents: false</code>, <code>edit.php</code> stub from manifest <code>first_sentence</code> | |||
|- | |||
| 4 || Build Main Page wikitext from manifest tree + selections; <code>edit.php</code> | |||
|- | |||
| 5 || Sync uploads only for file titles referenced by selected pages with full content | |||
|- | |||
| 6 || <code>update --quick</code>; reload httpd | |||
|} | |||
'''MVP fallback:''' Import full template, then delete unselected pages and overwrite stub-only pages from manifest — acceptable for Phase 2 if export is ~90 pages. | |||
=== Phase C — Uploads === | |||
Only rsync upload files referenced by pages with <code>contents: true</code> (parse <code>[[File:...]]</code> in imported bodies). | |||
== Portal implementation == | |||
{| File !! Change | |||
|- | |||
| <code>portal/public/get-started.php</code> || Multi-step wizard; store progress in <code>$_SESSION['onboarding']</code> | |||
|- | |||
| <code>portal/public/api/demo-manifest.php</code> || '''New''' — serve manifest (auth required) | |||
|- | |||
| <code>portal/lib/jobs.php</code> || Accept environment + selection; validate against manifest | |||
|- | |||
| <code>portal/lib/onboarding.php</code> || '''New''' — validation, defaults, tree helpers | |||
|- | |||
| <code>portal/public/styles.css</code> || Checklist table, indented tree, disabled PARA card | |||
|- | |||
| <code>portal/bin/provision-wiki.php</code> || Pass new args to <code>create-wiki.sh</code> | |||
|} | |||
'''Validation rules:''' | |||
* Slug rules unchanged | |||
* Every manifest title appears at most once in selection | |||
* If parent unchecked but child checked → auto-check parent '''Page''' (recommended) | |||
* If user clears everything → allow but warn (“Your wiki will have an empty Main Page”) | |||
== Registry & observability == | |||
{| Item !! Purpose | |||
|- | |||
| <code>wiki_registry.wiki_environment</code> || Analytics; support | |||
|- | |||
| <code>admin_events</code> / extend <code>wiki_provisioned</code> payload || Log environment + page counts | |||
|- | |||
| Job JSON retain selection || Debugging failed provisions | |||
|} | |||
Optional: store compact selection JSON in <code>wiki_registry.provisioning_options</code> (TEXT). | |||
== Phased delivery == | |||
=== Phase 1 — Foundation (1–2 weeks) === | |||
* SQL migration: <code>wiki_environment</code>, optional <code>provisioning_options</code> | |||
* <code>build-demo-page-manifest.php</code> + hook into <code>export-demo-template.sh</code> | |||
* <code>create-wiki.sh --environment=default</code> (skip import) | |||
* Wizard Steps 1–2–4 only (environment + slug; demo path still full import) | |||
* Job schema + <code>provision-wiki.php</code> wiring | |||
'''Deliverable:''' User can choose stock wiki vs full demo clone. | |||
=== Phase 2 — Page checklist UI (1 week) === | |||
* Manifest API + Step 3 tree UI (checkboxes; defaults all on) | |||
* Persist selection in job JSON | |||
* PARA option shown disabled | |||
'''Deliverable:''' UI matches requirements; still full import if any page selected (temporary). | |||
=== Phase 3 — Selective import (2–3 weeks) === | |||
* <code>import-wiki-selection.php</code> with Page/Contents semantics | |||
* Generated Main Page from selections | |||
* Upload filtering | |||
* Adjust <code>TEMPLATE_MIN_PAGES</code> logic (count only selected pages) | |||
'''Deliverable:''' Full requirements for static template path on [[New User Onboarding]]. | |||
=== Phase 4 — Polish (1 week) === | |||
* User info: timezone prompt (optional; apply via MW user option after first login) | |||
* Signup audit enrichment (IP/geo/browser) if desired | |||
* Docs: update roadmap §1, <code>wiki-template.md</code>, sync this page | |||
* E2E test wiki slugs on staging | |||
== Testing plan == | |||
{| Scenario !! Expected | |||
|- | |||
| Default wiki || Stock Main Page; ~1–5 core pages; no demo titles | |||
|- | |||
| Demo, all checked || Parity with current full import (~88 pages) | |||
|- | |||
| Demo, Page only everywhere || All titles exist; each body ≈ one sentence | |||
|- | |||
| Demo, mixed || Spot-check full vs stub vs absent | |||
|- | |||
| Demo, only Personal subtree || Main Page links only to selected branch | |||
|- | |||
| Re-run job failure || Job error surfaced; no partial registry orphan | |||
|- | |||
| Existing user || <code>get-started.php</code> still shows “already have wiki” | |||
|} | |||
Automate: shell test that provisions <code>templatetest-default</code> and <code>templatetest-selective</code> on EC2 after deploy. | |||
== Risks & mitigations == | |||
{| Risk !! Mitigation | |||
|- | |||
| Manifest drift vs demo wiki || Regenerate on every <code>export-demo-template.sh</code>; CI check manifest age | |||
|- | |||
| Main Page link rot || Generate Main Page programmatically, don’t filter by deletion | |||
|- | |||
| Long provisioning with full import then trim || Move to selective import in Phase 3; show progress in job UI | |||
|- | |||
| Parent/child checkbox UX || Auto-select ancestors; indent tree clearly | |||
|- | |||
| Large POST from 84+ pages || Store selection server-side in session; job references session id or compact bitset | |||
|} | |||
== What stays unchanged == | |||
* Google OIDC / Authentik login | |||
* One wiki per user | |||
* Async job polling | |||
* <code>GoalStrivingAccess</code> ACL after first wiki login | |||
* Demo wiki as golden source (<code>demo.goalstriving.org</code> + export pipeline) | |||
* PARA forms on personal wikis (installed by deploy; not part of onboarding wizard) | |||
== Recommended first PR slice == | |||
Smallest useful increment: '''Phase 1''' — environment toggle + <code>--environment=default</code>, plus manifest generator (no UI checklist yet). Unblocks users who want a blank wiki immediately while checklist work proceeds in parallel. | |||
== Republish from git == | |||
<pre> | |||
sudo GOALSTRIVING_CURSOR_WIKI_PAGE="Cursor User Onboarding Implementation Plan" \ | |||
GOALSTRIVING_CURSOR_WIKI_SOURCE=/opt/goalstriving-wiki/templates/cursor-user-onboarding-implementation-plan.wiki \ | |||
/usr/local/bin/publish-cursor-wiki-page.sh | |||
</pre> | |||