Cursor User Onboarding Implementation Plan: Difference between revisions

From Knowledge Commons
Jump to navigation Jump to search
Created page with "This page details how the user onboarding experience was configured."
 
CursorBot (talk | contribs)
Cursor: publish user onboarding implementation plan
 
Line 1: Line 1:
This page details how the user onboarding experience was configured.
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>

Latest revision as of 19:06, 4 September 2026

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 docs/wikifam_community_roadmap.md §1 and Cursor planning session (September 2026).

Goals

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), wiki_registry name/avatar fields, wiki_member_name_changes, timezone default from Google at registration.

Current state

Today the flow is: Google login → slug on goalstriving.org/get-started.php → async job → create-wiki.shfull demo-template.xml import for every personal wiki.

  • No environment choice
  • No page checklist
  • Job JSON has no environment or template_selection
  • import-wiki-template.sh only supports full XML dump import

Key repo files today:

Area Path Role
Portal UI portal/public/get-started.php Slug form + job polling only
Jobs portal/lib/jobs.php Async provision job JSON
Worker portal/bin/provision-wiki.php Calls create-wiki.sh
Provision scripts/create-wiki.sh DB + MW install + full template import
Import scripts/import-wiki-template.sh Full XML + uploads rsync
Template export scripts/export-demo-template.sh Golden export from demo wiki
Registry sql/auth-schema.sql wiki_members, invites, audit

Target user experience

Multi-step wizard on goalstriving.org/get-started.php (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

  • [slug].goalstriving.org (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:

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

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)

Demo page manifest

Problem: Wizard needs a stable tree independent of live demo edits during a deploy window.

Solution: Generate templates/demo-page-manifest.json on each export-demo-template.sh run (server path: /etc/goalstriving/templates/demo-page-manifest.json).

Example structure:

{
  "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": { }
}

Generator: New script scripts/build-demo-page-manifest.php:

  1. Read demo Main Page wikitext → parse links hierarchy
  2. For each linked page in export XML, extract first sentence (text before first blank line / heading)
  3. Write manifest alongside demo-template.xml
  4. Optionally commit manifest to git for portal dev without EC2

Portal: GET /api/demo-manifest.php (authenticated) returns manifest JSON for wizard Step 3.

Job schema extension

Extend startProvisioningJob() in portal/lib/jobs.php:

{
  "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 }
    }
  }
}
  • environment: default → ignore template_selection; skip template import entirely
  • environment: demo_preload → require template_selection; default all true if omitted (backward compat during rollout)

Pass to worker:

create-wiki.sh "$SLUG" "$SITE_NAME" "$ADMIN" \
  --environment=demo_preload \
  --selection-file=/tmp/job-{id}-selection.json

Backend: selective import

Phase A — Default wiki path (small)

create-wiki.sh changes:

  • Accept --environment=default|demo_preload
  • If default: skip import-wiki-template.sh; verify page count ≥ 1; lower or bypass TEMPLATE_MIN_PAGES check
  • Store environment in wiki_registry (new column wiki_environment ENUM('default','demo_preload') — migration in sql/)

Phase B — Selective demo import (core)

Recommended: new scripts/import-wiki-selection.php (Maintenance runner):

1 Delete stock Main Page (existing behavior)
2 For each selected title with contents: true, import that page from XML
3 For page: true, contents: false, edit.php stub from manifest first_sentence
4 Build Main Page wikitext from manifest tree + selections; edit.php
5 Sync uploads only for file titles referenced by selected pages with full content
6 update --quick; 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 contents: true (parse File:... in imported bodies).

Portal implementation

portal/public/get-started.php Multi-step wizard; store progress in $_SESSION['onboarding']
portal/public/api/demo-manifest.php New — serve manifest (auth required)
portal/lib/jobs.php Accept environment + selection; validate against manifest
portal/lib/onboarding.php New — validation, defaults, tree helpers
portal/public/styles.css Checklist table, indented tree, disabled PARA card
portal/bin/provision-wiki.php Pass new args to create-wiki.sh

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

wiki_registry.wiki_environment Analytics; support
admin_events / extend wiki_provisioned payload Log environment + page counts
Job JSON retain selection Debugging failed provisions

Optional: store compact selection JSON in wiki_registry.provisioning_options (TEXT).

Phased delivery

Phase 1 — Foundation (1–2 weeks)

  • SQL migration: wiki_environment, optional provisioning_options
  • build-demo-page-manifest.php + hook into export-demo-template.sh
  • create-wiki.sh --environment=default (skip import)
  • Wizard Steps 1–2–4 only (environment + slug; demo path still full import)
  • Job schema + provision-wiki.php 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)

  • import-wiki-selection.php with Page/Contents semantics
  • Generated Main Page from selections
  • Upload filtering
  • Adjust TEMPLATE_MIN_PAGES 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, wiki-template.md, sync this page
  • E2E test wiki slugs on staging

Testing plan

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 get-started.php still shows “already have wiki”

Automate: shell test that provisions templatetest-default and templatetest-selective on EC2 after deploy.

Risks & mitigations

Manifest drift vs demo wiki Regenerate on every export-demo-template.sh; 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
  • GoalStrivingAccess ACL after first wiki login
  • Demo wiki as golden source (demo.goalstriving.org + 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 + --environment=default, plus manifest generator (no UI checklist yet). Unblocks users who want a blank wiki immediately while checklist work proceeds in parallel.

Republish from git

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