Files
jiapuapp/docs/superpowers/plans/2026-07-12-g01-visual-shell.md
T

222 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# G-01 Visual Shell Implementation Plan
> For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox syntax for tracking.
**Goal:** Rebuild the Android “我的家谱” G-01 page as the approved 家祠卷轴 design with verified local PNG assets and stable mock presentation data.
**Architecture:** pages/genealogy/index.vue owns local visual states only. It composes a heritage header, paper-slip list items, and safe bottom navigation; it does not make remote API calls during this visual-construction phase.
**Tech Stack:** uni-app, Vue 3 script setup, SCSS/rpx, local RGBA PNG/JPG assets, PowerShell checks.
## Global Constraints
- Android only; verify 360 × 800 and 320 × 568 without overlap.
- No API, authentication, packaging, dependency, or unrelated-flow changes.
- Every functional icon is a local RGBA PNG under static/assets/icons/.
- Header uses the confirmed original brand/jiapu-seal-logo.png in the left safe area; title is centered; notification dot renders only for unread messages.
- Tabbar is fixed at the bottom, has 64dp content plus Android navigation inset, and keeps the icon and label clear of the lower edge.
- Do not mark G-01 design complete until assets, normal/empty/loading states, and small-screen checks have evidence.
## File Responsibilities
| File | Responsibility |
| --- | --- |
| static/assets/icons/genealogy/*-v2.png | Four compact antique-gold G-01 shortcut icons. |
| static/assets/icons/action/add-v2.png | The compact 新建家谱 icon. |
| static/assets/icons/common/chevron-right-v2.png | Compact right-arrow asset for the paper-slip list row. |
| static/assets/icons/tab/*-v4.png | Default and active 24dp tab icon pairs. |
| components/PageHeader.vue | Heritage header, original Logo, notification PNG and optional dot. |
| components/AppTabbar.vue | Fixed Android-safe three-tab navigation. |
| components/GenealogyCard.vue | Compact paper-slip genealogy list row. |
| pages/genealogy/index.vue | G-01 content, local state and route actions. |
| tests/g01-visual-contract.ps1 | Asset and static page-contract checks. |
## Task 1: Produce and register G-01 visual assets
**Files:**
- Create: static/assets/icons/genealogy/tree-v2.png
- Create: static/assets/icons/genealogy/members-v2.png
- Create: static/assets/icons/genealogy/generation-poem-v2.png
- Create: static/assets/icons/genealogy/application-v2.png
- Create: static/assets/icons/action/add-v2.png
- Create: static/assets/icons/common/chevron-right-v2.png
- Create: static/assets/icons/tab/{genealogy,family,profile}-v4.png
- Create: static/assets/icons/tab/{genealogy,family,profile}-active-v4.png
- Create: tests/g01-visual-contract.ps1
- Modify: docs/design/G01_我的家谱_设计记录.md
**Interfaces:**
- Consumes: D1 icon rules and the G-01 asset table.
- Produces: the listed asset paths; no legacy static/icons/tab-*.png consumer remains.
- [x] **Step 1: Write the failing asset contract**
$root = Split-Path -Parent $PSScriptRoot
$requiredAssets = @(
'static/assets/icons/brand/jiapu-seal-logo.png',
'static/assets/icons/common/notice-v3.png',
'static/assets/icons/genealogy/tree-v2.png',
'static/assets/icons/genealogy/members-v2.png',
'static/assets/icons/genealogy/generation-poem-v2.png',
'static/assets/icons/genealogy/application-v2.png',
'static/assets/icons/action/add-v2.png',
'static/assets/icons/common/chevron-right-v2.png',
'static/assets/icons/tab/genealogy-v4.png',
'static/assets/icons/tab/genealogy-active-v4.png',
'static/assets/icons/tab/family-v4.png',
'static/assets/icons/tab/family-active-v4.png',
'static/assets/icons/tab/profile-v4.png',
'static/assets/icons/tab/profile-active-v4.png'
)
foreach ($asset in $requiredAssets) {
if (-not (Test-Path -LiteralPath (Join-Path $root $asset))) {
throw "Missing G-01 visual asset: $asset"
}
}
Write-Output 'PASS G-01 visual contract'
- [x] **Step 2: Run the contract and confirm it fails**
Run: powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\g01-visual-contract.ps1
Expected: an error that names tree-v2.png as missing.
- [x] **Step 3: Generate and validate every icon**
Generate each asset separately as a tight 96 × 96px transparent PNG. Shortcut and add icons use antique-gold #B58A4B with the approved restrained double-line style. Tab pairs use the same 24dp silhouette in default ink #342A24 and selected cinnabar #A33B2B; no text, clouds, leaves, shadows, or excess transparent padding.
- [x] **Step 4: Inspect and register accepted assets**
Inspect Tabs at 46rpx and shortcuts at 48rpx. Reject opaque corners, excess canvas padding, unrecognizable semantics, and any default/selected silhouette mismatch. Update the G-01 asset table with actual path, 96 × 96px, transparency result, and display-size result. Do not tick page-completion boxes yet.
- [x] **Step 5: Re-run the asset contract**
Expected: PASS G-01 visual contract.
## Task 2: Rebuild header and Android-safe Tabbar
**Files:**
- Modify: components/PageHeader.vue
- Modify: components/AppTabbar.vue
- Modify: tests/g01-visual-contract.ps1
**Interfaces:**
- Produces: PageHeader title=我的家谱 with unreadCount, and AppTabbar active=genealogy.
- [x] **Step 1: Extend the failing static contract**
$header = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'components/PageHeader.vue')
$tabbar = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'components/AppTabbar.vue')
if ($header -notmatch 'jiapu-seal-logo\.png') { throw 'Header does not use the approved brand PNG.' }
if ($header -notmatch 'notice-v3\.png') { throw 'Header does not use the approved notice PNG.' }
if ($header -notmatch 'unreadCount\s*>\s*0') { throw 'Header badge is not conditional on unread count.' }
if ($tabbar -match '/static/icons/tab-') { throw 'Tabbar still references rejected legacy tab assets.' }
if ($tabbar -notmatch 'safe-area-inset-bottom') { throw 'Tabbar has no Android safe-area padding.' }
if ($tabbar -notmatch 'font-size:\s*24rpx') { throw 'Tabbar label size is below the approved G-01 size.' }
- [x] **Step 2: Confirm the contract fails before components change**
Run the focused contract.
Expected: failure describing the legacy header or Tabbar implementation.
- [x] **Step 3: Implement the header**
Use image-only controls: an 88rpx Logo touch area, centered title, and equal-width 88rpx notice touch area using notice-v3.png. Add v-if unreadCount > 0 for the cinnabar dot. Use the header line-art PNG over a cinnabar base. Do not render text labels for Logo or notification action.
- [x] **Step 4: Implement the Tabbar**
Map every item to its v4 default/active PNG paths and choose by active === item.key. Keep a paper-white fixed bar, visible content height 128rpx, padding-bottom env(safe-area-inset-bottom), icon 48rpx, label 24rpx, and each touch target at least 96rpx. Do not use gap.
- [x] **Step 5: Re-run the contract**
Expected: PASS G-01 visual contract.
## Task 3: Rebuild G-01 content and presentation states
**Files:**
- Modify: components/GenealogyCard.vue
- Modify: pages/genealogy/index.vue
- Modify: tests/g01-visual-contract.ps1
**Interfaces:**
- Consumes: genealogies and notifications from @/data/mock.js.
- Produces: isLoading, hasGenealogies, createdGenealogies, and joinedGenealogies visual branches.
- [x] **Step 1: Add the failing local-state contract**
$page = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/genealogy/index.vue')
if ($page -match "from '@/utils/api\.js'") { throw 'G-01 visual phase must not call the remote API.' }
foreach ($state in @('isLoading', 'hasGenealogies', 'createdGenealogies', 'joinedGenealogies')) {
if ($page -notmatch $state) { throw "G-01 is missing presentation state: $state" }
}
foreach ($asset in @('tree-v2.png', 'members-v2.png', 'generation-poem-v2.png', 'application-v2.png', 'add-v2.png')) {
if ($page -notmatch [regex]::Escape($asset)) { throw "G-01 does not consume $asset" }
}
- [x] **Step 2: Confirm the contract fails on the legacy page**
Expected: failure for the API import or missing visual state.
- [x] **Step 3: Implement the page state owner**
Remove appApi, genealogyContext, and the mounted API call. Import genealogies and notifications from @/data/mock.js, then define:
const isLoading = ref(false)
const list = ref(genealogies)
const hasGenealogies = computed(() => list.value.length > 0)
const createdGenealogies = computed(() => list.value.filter((item, index) => index === 0))
const joinedGenealogies = computed(() => list.value.filter((item, index) => index > 0))
Retain only route navigation: tree /pages/tree/index, members /pages/genealogy/detail, generation poem /pages/content/list?type=poem, applications /pages/genealogy/applications, create /pages/genealogy/create, search /pages/genealogy/search, and notifications /pages/notification/index.
- [x] **Step 4: Implement approved compact layout**
Compose heritage header, current-genealogy paper slip, four equal shortcut entries with v2 assets, separate 我创建的 / 我加入的 groups, compact paper-slip rows, and the add button. Implement a distinct loading state and an empty paper/scroll state with 新建家谱 and 搜索并申请加入. Apply paper texture to the page and mountain/bamboo only to the lower content region. Add bottom content padding that clears the fixed Tabbar.
- [x] **Step 5: Simplify GenealogyCard.vue**
Use a seal-style surname block, title, short location/member metadata, identity label, and common/chevron-right-v2.png. Remove the legacy navy cover, motto, and active-member count. Ensure long copy uses min-width: 0, overflow: hidden, and text-overflow: ellipsis.
- [x] **Step 6: Re-run the focused contract**
Expected: PASS G-01 visual contract.
## Task 4: Verify and update the project record
**Files:**
- Modify: docs/design/G01_我的家谱_设计记录.md
- Modify: docs/规划.md
- Test: tests/g01-visual-contract.ps1
- Test: tests/compile-audit.ps1
- Test: tests/uni-scss-injection.ps1
- [x] **Step 1: Run the automated checks**
Run:
powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\g01-visual-contract.ps1
powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\compile-audit.ps1
powershell -ExecutionPolicy Bypass -File C:\Users\Rain\Desktop\job\jiapuapp\tests\uni-scss-injection.ps1
Expected: each command prints its PASS result.
- [ ] **Step 2: Verify at Android reference sizes**
Inspect 360 × 800 and 320 × 568. Confirm no overlap among Logo, title, and bell; notice dot only appears with unread entries; shortcut labels remain one line; list text truncates instead of overlaps; create action clears the Tabbar; all three Tab labels remain fully visible above system navigation.
- [ ] **Step 3: Update only verified design state**
In the G-01 record, tick only conditions backed by Tasks 12 and the two viewport checks. In the overall planning document, leave G-01 unchecked if even one state, asset, or viewport condition remains incomplete; otherwise record visual shell implemented and verified.
- [ ] **Step 4: Commit only when Git becomes available**
If a Git worktree exists, commit changed visual-shell files with message: feat: build G01 genealogy visual shell. If Git remains unavailable, report that no commit was created and do not initialize a repository.
## Plan Self-Review
- Task 1 covers local assets and transparency checks.
- Task 2 covers the Logo, conditional notification dot, and safe Tabbar.
- Task 3 covers G-01 normal, loading, and empty states plus approved compact layout.
- Task 4 requires automated and small-screen verification before any completion status changes.