Files
web/docs/superpowers/plans/2026-05-01-showcase-management.md
xuyueandClaude Opus 5.5 47d4679984 chore: 合并为单仓库,统一部署流程
- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件
- 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow:
  构建前端上传到 build/,再在服务器上 git pull 并重建容器

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:02:12 +08:00

5.5 KiB

Showcase Management Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Add a Dashboard-based management page for awards and awarded submissions that controls the existing student-facing showcase.

Architecture: Keep the existing public showcase API unchanged. Add admin-only django-ninja management endpoints under submission/api.py, extend the TypeScript API client and shared types, then add a focused ShowcaseManage.vue Dashboard page wired into the existing router and sidebar.

Tech Stack: Django, django-ninja, Django TestCase, Vue 3 Composition API, TypeScript, Naive UI, Axios.


Task 1: Backend Management API

Files:

  • Modify: api/submission/schemas.py

  • Modify: api/submission/api.py

  • Test: api/submission/tests.py

  • Step 1: Write failing API tests

Append tests to api/submission/tests.py that create an admin user, a normal user, an award, and a submission. Cover forbidden normal-user access, award creation/update, adding the same submission twice, and student showcase visibility after removal/deactivation.

Run: uv run manage.py test submission

Expected: FAIL because /api/submission/showcase/manage/awards endpoints do not exist.

  • Step 2: Add schema classes

Add management schemas in api/submission/schemas.py:

class AwardManageIn(Schema):
    name: str
    description: str = ""
    sort_order: int = 0
    is_active: bool = True
    item_ordering: str = "manual"


class AwardManageOut(Schema):
    id: int
    name: str
    description: str
    sort_order: int
    is_active: bool
    item_ordering: str
    item_count: int


class AwardItemIn(Schema):
    submission_id: UUID
    sort_order: int = 0


class AwardItemUpdateIn(Schema):
    sort_order: int = 0


class AwardItemManageOut(Schema):
    id: int
    submission_id: UUID
    username: str
    task_title: str
    task_display: int
    score: float
    view_count: int
    sort_order: int
    awarded_at: datetime
    has_prompt_chain: bool
  • Step 3: Add admin-only endpoints

In api/submission/api.py, import admin_required and the new schemas. Add endpoints before /showcase/{submission_id}/ so static manage/... paths resolve correctly:

  • GET /showcase/manage/awards
  • POST /showcase/manage/awards
  • PUT /showcase/manage/awards/{award_id}
  • DELETE /showcase/manage/awards/{award_id}
  • GET /showcase/manage/awards/{award_id}/items
  • POST /showcase/manage/awards/{award_id}/items
  • PUT /showcase/manage/items/{item_id}
  • DELETE /showcase/manage/items/{item_id}

Use admin_required, get_object_or_404, Count, Exists, and OuterRef. Validate item_ordering against ItemOrdering.values.

  • Step 4: Run backend tests

Run: uv run manage.py test submission

Expected: PASS.

Task 2: Frontend API Types And Client

Files:

  • Modify: client/src/utils/type.ts

  • Modify: client/src/api.ts

  • Step 1: Add TypeScript types

Add:

export type ItemOrdering = "manual" | "awarded_at" | "score" | "view_count"

export interface AwardManageIn {
  name: string
  description: string
  sort_order: number
  is_active: boolean
  item_ordering: ItemOrdering
}

export interface AwardManageOut extends AwardManageIn {
  id: number
  item_count: number
}

export interface AwardItemIn {
  submission_id: string
  sort_order: number
}

export interface AwardItemUpdateIn {
  sort_order: number
}

export interface AwardItemManageOut {
  id: number
  submission_id: string
  username: string
  task_title: string
  task_display: number
  score: number
  view_count: number
  sort_order: number
  awarded_at: string
  has_prompt_chain: boolean
}
  • Step 2: Extend API client

Import the new types in client/src/api.ts and add Showcase methods:

  • listManageAwards()

  • createAward(payload)

  • updateAward(id, payload)

  • deleteAward(id)

  • listAwardItems(id)

  • addAwardItem(id, payload)

  • updateAwardItem(itemId, payload)

  • deleteAwardItem(itemId)

  • Step 3: Run type/build check

Run: npm run build from client/.

Expected: PASS.

Task 3: Dashboard Route And Page

Files:

  • Modify: client/src/router.ts

  • Modify: client/src/pages/Dashboard.vue

  • Create: client/src/pages/ShowcaseManage.vue

  • Step 1: Add route and menu

Add /dashboard/showcase child route named showcase-manage. Add a Dashboard sidebar item labelled 作品广场, visible to admin and super.

  • Step 2: Create management page

Build ShowcaseManage.vue with:

  • Left award list and new award button.

  • Right award edit form.

  • Award items table with sortable numeric input and remove button.

  • Submission search table using existing Submission.list().

  • Add-to-award button for each searched submission.

  • Step 3: Run frontend build

Run: npm run build from client/.

Expected: PASS.

Task 4: End-To-End Verification

Files:

  • No production file edits expected.

  • Step 1: Run backend tests

Run: uv run manage.py test submission from api/.

Expected: PASS.

  • Step 2: Run frontend build

Run: npm run build from client/.

Expected: PASS.

  • Step 3: Manual smoke path

Start the app with existing dev command if needed. Log in as an admin user, visit /dashboard/showcase, create an award, add a submission, then visit /showcase and confirm the awarded work appears.