kongkx 6932906327
All checks were successful
CI / Typecheck, test & build (push) Successful in 2m9s
CI / Deploy to Cloudflare Workers (push) Successful in 1m23s
replace Start prerender with Vite SPA
2026-08-31 01:28:48 +08:00
2026-08-31 01:28:48 +08:00

gig-admin

Standalone admin dashboard for the gig-platform backend (/api/admin/v1/*).

React 19 · TanStack Start (SPA mode) · TanStack Query/Table · shadcn/ui · Tailwind v4 · TypeScript.

Quick start

cp .env.example .env          # VITE_API_BASE_URL → backend origin
pnpm install
pnpm dev                      # http://localhost:3000

Log in with an admin-role account (Passport password grant against POST /api/admin/v1/auth/login/password). To seed a local admin, run in the backend repo:

ddev exec php artisan tinker storage/app/e2e-admin-seed.php
# → admin@gig.local / Admin@12345

Scripts

Command Purpose
pnpm dev dev server on :3000
pnpm build / pnpm preview production build / preview
pnpm typecheck tsc --noEmit
pnpm test vitest (API client envelope/refresh/error tests)
pnpm gen:api regenerate src/api/types.gen.ts from the backend's private admin OpenAPI spec (../gig-platform/storage/app/api-docs/admin/openapi.yaml; run ddev artisan api-docs:generate there first)

Uploads

api.upload(path, formData) is the multipart path. rawRequest deliberately does not set Content-Type for a FormData body — the browser must set it itself so the multipart boundary is included; setting it by hand makes the server see an empty upload (a 422 rather than a 202). fetch reports no upload progress, so upload UIs stay indeterminate.

Deploy

The app is a client-rendered Vite SPA served as static assets by a Cloudflare Worker (wrangler.jsonc, not_found_handling: single-page-application). Cloudflare returns dist/index.html for every client route.

Manual deploy (needs wrangler login or CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID in your env):

pnpm cf:deploy    # vite build → copy shell to index.html → wrangler deploy

CI/CD — every push & PR runs typecheck + test + build; pushes to main build and deploy to Cloudflare. Two mirrored pipelines are provided:

Platform Workflow
GitHub Actions .github/workflows/ci.yml
Gitea Actions .gitea/workflows/ci.yml

Configure these on the repo before the first deploy:

Type Name Value
Variable VITE_API_BASE_URL backend API origin baked into the build
Secret CLOUDFLARE_API_TOKEN token with "Edit Cloudflare Workers" scope
Secret CLOUDFLARE_ACCOUNT_ID Cloudflare account id
  • GitHub: Settings → Secrets and variables → Actions.
  • Gitea: Repo → Settings → Actions → Secrets / Variables. Actions must be enabled and an act_runner registered with the ubuntu-latest label (use an image such as catthehacker/ubuntu:act-22.04).

Architecture notes

  • Auth: Bearer tokens in localStorage (zustand persist). src/api/client.ts unwraps the {success, data, message} envelope, sends X-Language-Locale, and does a single-flight refresh-then-retry on 401 (POST /api/v1/auth/refresh-token, client_machine_name=admin-api-client).
  • Permissions: GET /auth/me returns meta.roles / meta.permissions; nav items and routes gate on them (super-admin passes everything).
  • Lists: useListPage + <DataTable> bind to the backend's pagination {current_page, page_size, …} shape (page/page_size params).
  • Generated types (types.gen.ts) are reference-only (@ts-nocheck — scribe emits duplicate operationIds); hand-written shapes live in src/api/types.ts.

Features (milestone 1)

  • 分类管理:分类树 CRUD、待审核队列通过/驳回/合并到已有分类)
  • 内容工作室:机器人作者(暂停/恢复)、系列、文章、子话题、分类简报、风格预设、 Agent 接入令牌(签发一次性展示 / 吊销)
  • 用户与系统SID 保留规则、幸运号码、查询/分配;语言设置;推送设备;机器人会话令牌

Next milestones: moderation reports (comment / file-x), dashboard stats (needs backend endpoints).

Description
No description provided
Readme 570 KiB
Languages
TypeScript 99.3%
CSS 0.5%