chore: seal Design Vision v1 and monorepo scaffold

Archive the differentiated YuXinGu product docs, AI engineering system,
design contract, and Go/Vue scaffold. Next execution prioritizes Cece-parity
over early innovation (see .ai/product/STRATEGY.md).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-02 16:00:44 +08:00
co-authored by Cursor
parent 2686866376
commit e2e49aaac4
193 changed files with 8854 additions and 1851 deletions
+67
View File
@@ -0,0 +1,67 @@
# AI Engineering System
Machine-readable rules for Cursor / Claude Code / other agents.
**Source of truth for engineering constraints.** Prompts are helpers, not the core.
## Priority (what AI depends on most)
1. `constitution.md` — laws
2. `architecture.md` — layers
3. `domain.md` — ubiquitous language
4. `patterns/` — how to implement
5. `examples/` — copy shapes
6. `playbooks/` — step flows
7. `review.md` + `definition-of-done.md` + `checklists/`
8. `prompts/` — optional task templates
Also always: `ai-contract.md`, `forbidden.md`, `file-map.md`, `workflow.md`, `commands.md`, `adr/`.
## Tree
```
.ai/
├── constitution.md
├── architecture.md
├── tech-stack.md
├── domain.md
├── domain/
│ └── domain-map.md # DDD contexts / aggregates
├── product/
│ ├── feature-map.md # 愈心谷 Feature Tree
│ └── cece-feature-map.md
├── file-map.md
├── workflow.md
├── ai-contract.md
├── coding.md
├── api.md
├── database.md
├── ui.md # IA pointer → design/
├── design/ # AI Design System Contract
│ ├── design-system.md
│ ├── component-catalog.md
│ └── platform/
├── deployment.md
├── testing.md
├── security.md
├── review.md
├── definition-of-done.md
├── forbidden.md
├── commands.md
├── adr/
├── patterns/
├── playbooks/
├── checklists/
├── examples/
└── prompts/ # auxiliary
```
## Cursor
`.cursor/rules|templates|commands` are **symlinks** into this directory.
Truth = `.ai/` only. See `../.cursor/README.md`.
## Evolution
See `ROADMAP.md` — Phase 2/3 (anti-patterns, metrics, gates, memory, graph, mcp, skills) are deferred on purpose.
Root entry: `AGENTS.md` · `CLAUDE.md`
+38
View File
@@ -0,0 +1,38 @@
# AI System Evolution Roadmap
Do **not** build everything at once. Rules have maintenance cost.
## Phase 1 — Now (shipped)
- Rules: constitution, architecture, domain, coding, api, database, ui, …
- ADR, patterns, examples, playbooks
- Review / DoD / checklists / forbidden / commands / workflow / file-map
- `ai-contract.md`
- Cursor runtime: `.cursor/*` → symlink → `.ai/` (no content copy)
**Invest next engineering time in:** polishing `patterns/`, `examples/`, `playbooks/` while building real features — not more rule files.
## Phase 2 — When the codebase grows
Add only when pain appears:
| Item | Why wait |
|---|---|
| `anti-patterns/` | Useful after real mistakes accumulate |
| `metrics.md` | Numbers matter once CI exists |
| `quality-gates.md` | Wire when lint/test gates are real |
| `memory/` (known-bugs, tech-debt, todo) | Fill from actual incidents |
## Phase 3 — Multi-agent / heavy automation
| Item | Why wait |
|---|---|
| `graph/domain.yaml` | Knowledge graph for relation reasoning |
| `mcp/*.json` | Structured context servers |
| `skills/<feature>/` | Packaged feature kits (login, payment, …) |
Markdown remains human-readable; JSON/YAML for machines — introduce when agents > 1 or retrieval latency hurts.
## Rule of thumb
If adding a rule file does not prevent a repeated AI failure this week, **do not add it**.
+20
View File
@@ -0,0 +1,20 @@
# ADR-0001 Use Golang for API
## Status
Accepted
## Decision
Backend is Go only (`apps/api`).
## Reason
1. Fits small team / AI-assisted CRUD + rule engines
2. Simple deploy (single binary)
3. Strong concurrency for future AI/proxy workloads
## Never
Never replace the API language with Node/Java/Python without a new ADR and explicit approval.
Legacy `server.py` is temporary and must not grow new product APIs.
+19
View File
@@ -0,0 +1,19 @@
# ADR-0002 Use gin HTTP framework
## Status
Accepted
## Decision
Use `github.com/gin-gonic/gin` for HTTP routing and middleware.
## Reason
1. Widely known; good AI completion quality
2. Enough features for REST MVP
3. Low ceremony
## Never
Never switch to echo/fiber/chi “for fun” mid-feature. Framework change needs a new ADR.
+20
View File
@@ -0,0 +1,20 @@
# ADR-0003 REST API (not GraphQL)
## Status
Accepted
## Decision
Public HTTP API is REST under `/api/v1` with envelope `{code,message,data}`.
## Reason
1. Simpler mental model for H5 + mini-program
2. Better Cursor/Claude reliability than GraphQL schemas mid-flight
3. Easier debugging with curl
## Never
Never replace with GraphQL without approval + new ADR.
Internal gRPC later is allowed only behind a new ADR; public clients stay REST.
+19
View File
@@ -0,0 +1,19 @@
# ADR-0004 JWT (or opaque Bearer) for auth
## Status
Accepted (direction)
## Decision
Clients send `Authorization: Bearer <token>`. Prefer JWT for stateless MVP; server may later move to opaque tokens + session store via new ADR.
## Reason
1. Works for H5 and future mini-program
2. Simple middleware story
## Never
Never invent parallel auth headers (`X-User-Id` as sole auth).
Never trust client-only “isVip” flags.
+22
View File
@@ -0,0 +1,22 @@
# ADR-0005 Redis — deferred
## Status
Deferred (not accepted for MVP)
## Decision
MVP does **not** require Redis. Use PostgreSQL + process memory only when safe.
## Reason
1. Reduce moving parts for first ship
2. Membership/session can start in Postgres
## When to revisit
Rate limiting, hot session cache, or distributed locks → write ADR-0005b Accepted before adding Redis.
## Never
Never add Redis “just in case” without an Accepted ADR update.
+21
View File
@@ -0,0 +1,21 @@
# ADR-0006 Monorepo + Vue3 user-h5
## Status
Accepted
## Decision
- npm workspaces Monorepo: `apps/*` + `packages/*`
- Primary client: Vue 3 + TypeScript + Vite (`apps/user-h5`)
- Shared network: `packages/sdk`
## Reason
1. Multi-platform path to mini-program via SDK adapters
2. AI-friendly explicit boundaries
3. Retire root Legacy HTML gradually
## Never
Never start a second unrelated frontend framework for user-h5 without ADR.
+36
View File
@@ -0,0 +1,36 @@
# AI Contract
Highest operational contract for every agent session.
## Before coding
MUST read:
1. `.ai/constitution.md`
2. `.ai/architecture.md`
3. `.ai/domain.md` (+ `domain/domain-map.md` when touching models/API)
4. `.ai/coding.md`
5. Task-relevant: `api.md` / `database.md` / `ui.md` / `security.md` / `product/feature-map.md`
6. UI tasks: `design/design-system.md` + `design/component-catalog.md` + `design/platform/*`
7. Relevant ADR under `.ai/adr/` if changing stack or style
## After coding
MUST:
1. Run / follow `.ai/review.md` and print Review block
2. Verify `.ai/definition-of-done.md`
3. Use matching checklist under `.ai/checklists/`
4. Prefer verifying with `.ai/commands.md` (build/test/health)
## Never
- Guess API shape
- Guess DB schema
- Guess product requirement
- Invent endpoints, tables, or domain words not in `.ai/domain.md` / OpenAPI / task
- Silently reverse an Accepted ADR
## If unclear
**ASK FIRST.** Do not invent. Do not “assume and continue”.
+49
View File
@@ -0,0 +1,49 @@
# API — Golden Rules
## Style
- REST only for public HTTP.
- Never use POST for pure queries (use GET).
- Verbs: GET / POST / PUT / DELETE.
- Prefix: `/api/v1`.
## Envelope (mandatory — never invent alternatives)
Success:
```json
{ "code": 0, "message": "success", "data": {} }
```
Error:
```json
{ "code": 10001, "message": "user not found" }
```
Forbidden shapes: `{ success: true }`, `{ ok: true }`, bare arrays as root.
## Error codes
- Start business codes at **10000**.
- 0 = success.
- Ranges: 1xxxx general/auth, 2xxxx profile, 3xxxx report/scale, 4xxxx order/membership, 5xxxx AI/companion.
## Pagination
Query: `page`, `page_size`
Data:
```json
{ "list": [], "total": 0, "page": 1, "page_size": 20 }
```
## Auth
- Bearer token in `Authorization` header when required.
- Resource ownership checked in service layer.
## Docs
- Public route changes update `proto/openapi.yaml` in the same change set.
- Do not invent endpoints that are not in OpenAPI / task spec.
+51
View File
@@ -0,0 +1,51 @@
# Architecture
## Allowed call graph
```
UI (user-h5 / mini-program)
→ packages/sdk
→ API Handler
→ Service
→ Repository
→ Database
```
## Forbidden
- Handler → Database (skip Service/Repository)
- UI → Database
- UI direct `fetch` to raw URLs (must use `@yuxingu/sdk` or `src/api` thin wrapper)
- Service importing Handler
- Circular package imports
- Giant `utils` / `common` dump packages
## Monorepo map
| Path | Role |
|---|---|
| `apps/api` | Only backend |
| `apps/user-h5` | Primary client (Vue3+TS) |
| `apps/mini-program` | Scaffold only until tasked |
| `apps/admin-h5` | Deferred |
| `packages/sdk` | Multi-platform HTTP client |
| `packages/types` | Shared TS types |
| `packages/utils` | Pure helpers |
| `packages/ui` | Design tokens |
| Root HTML / `server.py` | Legacy — do not extend |
## Feature flow (mandatory when adding a feature)
```
API route + handler
→ service
→ repository (if persistence)
→ migration (if schema change)
→ SDK / types update
→ UI page or component
→ test for money/scoring/auth paths
→ OpenAPI touch if public API changed
→ self-review
```
Missing migration or skipping service layer = incomplete.
+9
View File
@@ -0,0 +1,9 @@
# Checklist: Bugfix
- [ ] Failure mode stated
- [ ] Root cause located (file/func)
- [ ] Minimal fix only
- [ ] Regression test if scoring/auth/payment
- [ ] No unrelated refactors
- [ ] Build/tests green
- [ ] Review: Architecture / Security / Test / Scope
+16
View File
@@ -0,0 +1,16 @@
# Checklist: Feature
- [ ] Architecture layers respected
- [ ] Domain words match `.ai/domain.md`
- [ ] API (+ OpenAPI if public)
- [ ] Service
- [ ] Repository (if persistence)
- [ ] Migration (if schema)
- [ ] SDK/types (if client needs)
- [ ] UI (if user-facing)
- [ ] Test or smoke steps
- [ ] Docs touched if behavior user-visible
- [ ] `go test` / `npm run build:h5` as applicable
- [ ] Health still OK
- [ ] Review block printed
- [ ] DoD satisfied
+8
View File
@@ -0,0 +1,8 @@
# Checklist: Refactor
- [ ] Goal / non-goals stated (behavior unchanged unless asked)
- [ ] No ADR silently reversed
- [ ] Layers still clean
- [ ] File/function size improved toward limits
- [ ] Tests still pass; added if extracting unscored logic
- [ ] Review: Architecture / Readability / Test / Scope
+10
View File
@@ -0,0 +1,10 @@
# Checklist: Release
- [ ] main green: `go test ./...`, `npm run build:h5`
- [ ] Migrations applied plan documented
- [ ] Health endpoint verified
- [ ] No secrets in artifact
- [ ] Image tag ≠ `latest` (prod)
- [ ] OpenAPI matches deployed routes
- [ ] Changelog / version tag if shipping
- [ ] Rollback path known
+37
View File
@@ -0,0 +1,37 @@
# Coding — Golden Rules
## Size
- One responsibility per file.
- One responsibility per function.
- No function longer than **50** lines.
- No file longer than **400** lines (hard preference; split earlier if possible).
- No circular dependency.
## Go
- Business packages by domain: `auth`, `profile`, `report`, `order`, `payment` — not `utils`.
- Interface defined at **caller** (usually handler), implemented by service.
- First parameter of I/O methods: `context.Context`.
- Errors: `return fmt.Errorf("create user: %w", err)`.
- Never `panic` in request path.
- Never use package-level mutable globals for request state.
- Export comments required on public funcs (what / in / out / side effects).
## TypeScript / Vue
- `strict: true`. No casual `any`.
- Components: `PascalCase.vue` (`UserCard.vue`).
- Pages under `src/pages/`, composables under `src/hooks/`.
- No direct `fetch` in pages — use SDK.
- Shared domain types go to `packages/types`.
## Naming
- Consistent domain words: profile, report, scale, membership, order.
- Prefer boring clear names over clever short names.
## Comments
- Public APIs: always document.
- Do not narrate obvious code. Document intent, invariants, side effects.
+67
View File
@@ -0,0 +1,67 @@
# Commands — Do Not Guess
Run from repo root unless noted.
## Go API (`apps/api`)
```bash
export GOPROXY=https://goproxy.cn,direct # if download timeout
cd apps/api
go mod tidy
go build ./...
go test ./...
go run ./cmd/server
```
Health:
```bash
curl -s http://127.0.0.1:8080/api/v1/healthz
curl -s http://127.0.0.1:8080/api/v1/ping
```
## User H5
```bash
npm install
npm run dev:h5
npm run build:h5
```
## Docker / DB
```bash
docker compose -f deploy/docker-compose.yml up -d
docker compose -f deploy/docker-compose.yml down
```
## Lint (when configured)
```bash
# Go — after golangci-lint is added:
# cd apps/api && golangci-lint run
# H5 — after eslint is added:
# npm run lint -w @yuxingu/user-h5
```
## Migrations (when make targets exist)
```bash
# Preferred once Makefile lands:
# make migrate
# make migrate-down
# Until then: document the goose/migrate command used in the PR.
```
## Dev all (local)
```bash
# terminal 1
cd apps/api && go run ./cmd/server
# terminal 2
npm run dev:h5
```
+34
View File
@@ -0,0 +1,34 @@
# Project Constitution — 愈心谷
最高原则。与本文件冲突时,以本文件为准。
## Absolute Laws
1. Architecture never broken. Layers: UI → API → Service → Repository → Database. No skipping.
2. Readability > Cleverness.
3. Deterministic > Magic.
4. Simple > Complex.
5. Explicit > Implicit.
6. No hidden global state.
7. Every module independently testable.
8. Every feature deployable.
9. Every API documented (OpenAPI or apps/docs).
10. Every database change versioned (migration required).
## Product Laws (YuXinGu)
1. Never invent medical efficacy claims.
2. Never use fortune-telling / 吉凶祸福 wording.
3. Birthday and profile data are sensitive — minimize, authorize, allow delete.
4. Billing and unlock decisions happen on the server, never trust the client alone.
5. New product code lives in `apps/` and `packages/` only. Legacy root HTML is read-only unless the task is explicit migration.
## AI Laws
1. Obey `.ai/ai-contract.md` every session.
2. Load constitution → architecture → domain before writing code.
3. Never invent APIs/DB/domain words; never reverse Accepted ADRs silently.
4. Never modify files outside the current task scope.
5. Prefer patterns + examples + playbooks over prompts.
6. Prefer small diffs. One feature per change set.
7. Think → architecture check → code → commands → review → DoD.
+39
View File
@@ -0,0 +1,39 @@
# Database — Golden Rules
## Naming
- `snake_case` only for tables and columns.
- Good: `user_profile`, `payment_order`, `user_session`.
- Forbidden prefixes: `tbl_`, `t_`.
## Required columns on business tables
```
id
created_at
updated_at
deleted_at
```
## Types
- Never `varchar(5000)` as a habit.
- Prefer bounded `varchar(n)`.
- `TEXT` only when necessary (long content bodies).
- Timestamps: `timestamptz`.
## Keys & indexes
- Every foreign key indexed.
- Unique business keys enforced with UNIQUE.
## Migrations
- Schema change without migration = incomplete feature.
- Migrations live in `apps/api/migrations/`.
- Provide Up and Down when tool supports it.
## Soft delete
- Default: set `deleted_at`, do not hard delete user content in MVP.
- Queries must filter `deleted_at IS NULL` unless explicitly including deleted.
+17
View File
@@ -0,0 +1,17 @@
# Definition of Done
Code finished ≠ Done.
A feature is Done only when applicable items PASS:
- [ ] Code (compiles / typechecks)
- [ ] API (handler + service + repository as needed)
- [ ] Test (unit or listed smoke for critical paths)
- [ ] Migration (if schema changed)
- [ ] Docker / deploy notes (if new service or env)
- [ ] Docs (OpenAPI / short PRD note if user-visible)
- [ ] Review (`.ai/review.md` checklist output)
- [ ] Build (`go test ./...` and/or `npm run build:h5` for touched side)
- [ ] Health check still green (`/api/v1/healthz`)
If an item is N/A, state why. Silent skip = not Done.
+33
View File
@@ -0,0 +1,33 @@
# Deployment — Golden Rules
## Containers
- Every runnable service that ships to prod must have a Dockerfile.
- Never use image tag `latest` in production.
- Always semantic version tags: `v0.1.0` or git SHA.
## Health
- Liveness: `GET /api/v1/healthz` required.
- When DB is required for traffic: add readiness endpoint (e.g. `/api/v1/readyz`) that checks DB.
- Alias names `/health` `/readiness` `/liveness` may map to the above; keep one canonical path documented in OpenAPI.
## Config
- Secrets via env only. Commit `.env.example`, never `.env`.
- Required: `APP_ENV`, `HTTP_ADDR`, `DATABASE_URL`.
## CI
- No manual prod deploy as the happy path — CI builds and tags.
- Minimum gates: `go test ./...` (api), `npm run build:h5`.
## Local
```bash
docker compose -f deploy/docker-compose.yml up -d
cd apps/api && go run ./cmd/server
npm run dev:h5
```
If Go module download times out in CN: `export GOPROXY=https://goproxy.cn,direct`.
+15
View File
@@ -0,0 +1,15 @@
# AI Design System
Machine-readable **UI/UX/VI contract** for agents generating H5 / Mini Program / Web / App UI.
| File | Purpose |
|---|---|
| [design-system.md](design-system.md) | Foundation: tokens, color, type, spacing, motion, voice |
| [component-catalog.md](component-catalog.md) | Button / Card / Chat / Report / Membership … |
| [platform/h5.md](platform/h5.md) | Mobile Web implementation limits |
| [platform/mini-program.md](platform/mini-program.md) | WeChat constraints |
| [platform/website.md](platform/website.md) | Desktop / SEO / admin |
| [platform/flutter.md](platform/flutter.md) | Future native |
Runtime tokens: `packages/ui/src/tokens.css`
Product chrome / tabs: `../ui.md`
+233
View File
@@ -0,0 +1,233 @@
# Component Catalog — AI Contract
Agents MUST check this file + platform `components/` before creating UI.
Naming: PascalCase; domain words from `.ai/domain.md`.
Visual tokens: [design-system.md](design-system.md).
Ship path today: `apps/user-h5/src/components/` (Vue). Mini Program / Flutter map 1:1 by name.
Status: `exists` | `required` (build when first needed) | `future`
---
## Primitives
### Button
Status: **required**
Types ONLY: `Primary` · `Secondary` · `Ghost` · `Danger` · `Loading` · `Disabled`
| Prop | Notes |
|---|---|
| variant | primary / secondary / ghost / danger |
| loading | shows progress; blocks double submit |
| disabled | uses `--color-primary-disabled` or neutral |
| block | full width on H5 forms |
MUST NOT: `SpecialButton`, `CustomButton2`, one-off gradient buttons outside Primary.
Primary visual: pill + brand CTA gradient from design-system.
### IconTile
Status: **required**
Square/rounded tile for Explore / Home grid. Soft accent bg + symbol (△ ◆ ☯ 问), not emoji.
### Avatar
Status: **required**
Profile face placeholder (initials or soft color). Sizes: sm 32 / md 40 / lg 56.
### Tag / Chip
Status: **required**
Filter chips, Soft labels. Active = white surface + primary text + light shadow.
### Divider
Status: **required**`--color-border`, 1px.
### Skeleton
Status: **required** — list/card placeholders; calm pulse ≤300ms feel, no flashy shimmer rainbow.
### Toast / Banner
Status: **required** — success / error / info. Short copy; no fear wording.
---
## Layout chrome
### AppShell
Status: **exists** (TabBar + max-width column)
User column `max-width: var(--layout-max-user)`. Safe-area bottom padding.
### TabBar
Status: **exists**
Tabs: 首页 / 探索 / **问** / 陪伴 / 我的. Center Ask may use primary circle. Active = primary.
### TopBar
Status: **required**
Secondary pages: back · title · optional action. Soft wash or white; not heavy app bar.
### ContentSheet
Status: **required**
White rounded sheet over peach wash (home feed pattern).
---
## Forms
### TextField / DateField
Status: **required**
Label required · error · disabled · focus border soft primary. Birthday Decode uses compact year/month/day fields.
### FormSection
Status: **required** — label + control + helper/error.
Rules: Label, error, loading, disabled states always.
---
## Cards
### Card (base)
Status: **required**
Structure: Container → Padding (`--spacing-md`) → Content → Optional Action.
Surface white, `--radius-lg`, `--shadow-card`. No random card skins.
### FeatureCard
Status: **required** — Explore entry (icon + title + one line).
### ReportCard
Status: **required**
Decode / Match summary. Shows free conclusion; locked sections use PaywallLock. Footer disclaimer slot.
### MoodCard
Status: **required** — Companion daily mood entry/result. Soft, never clinical.
### SolarTermCard
Status: **required** — Todays SolarTerm title + short lifestyle tip (no 吉凶).
### SubscriptionCard
Status: **required**
Membership plans. Clear price · period · benefits. **MUST NOT** fake countdown / dark patterns. CTA = Primary Button.
### UnlockCard
Status: **required** — single Report / Match Unlock alternative to VIP.
---
## AI / Ask
### ChatThread
Status: **required** — scrollable Ask history; Profile context chip at top (Self / Other switch).
### ChatBubble
Status: **required**
User vs AI. AI bubble: soft surface, calm radius; no neon bot skins. Streaming = typing/skeleton, not decorative bounce spam.
### AIMessage
Status: **required**
Structured Ask answer: short answer · optional bullets · disclaimer when health-adjacent. Prefer structured blocks over wall of text.
### PromptChip
Status: **required** — suggested follow-ups under Ask input; path-aware (性格 / 关系 / 养生), never 运势.
### AskInputBar
Status: **required** — bottom composer; ≥44px hit; send loading state.
---
## Profile & social
### ProfileSwitcher
Status: **required** — Self / Other list; “帮 TA 测” entry.
### ShareCard
Status: **required** — Decode / ScaleResult share visual; brand + one conclusion line; no medical claims.
### ScaleQuestion / ScaleResultView
Status: **required** — progress · options · result type + CTA to Decode/Ask.
---
## Commerce
### PaywallLock
Status: **required** — blurred/locked reason+plan; CTA Unlock or Membership.
### OrderSummary
Status: **required** — plan/report line items before pay-mock.
---
## States
### EmptyState
Status: **required** — one sentence + one action.
### ErrorState
Status: **required** — message + retry/back.
### LoadingBlock
Status: **required** — page/section skeleton wrapper.
---
## Forbidden inventions
Without approval / catalog update:
- Parallel button systems
- “Glassmorphism” chat skins
- Emoji-only navigation
- New layout shells beside AppShell
- Countdown / guilt paywalls
---
## Extension rule
Need a new component → add a row here (name, status, props, do/dont) in the **same PR** as the first implementation. Then build under platform `components/`.
+276
View File
@@ -0,0 +1,276 @@
# AI Design System Contract — 愈心谷
**Mandatory.** Agents MUST read this before creating or modifying frontend UI
(`apps/user-h5`, `apps/mini-program`, `apps/admin-h5`, future website / Flutter).
| File | Role |
|---|---|
| [component-catalog.md](component-catalog.md) | Reusable components — check before inventing |
| [platform/h5.md](platform/h5.md) | Mobile Web (primary) |
| [platform/mini-program.md](platform/mini-program.md) | WeChat Mini Program |
| [platform/website.md](platform/website.md) | Desktop / marketing Web |
| [platform/flutter.md](platform/flutter.md) | Native app (future) |
Tokens: `packages/ui/src/tokens.css`
IA / tabs: `.ai/ui.md` · Domain: `.ai/domain.md`
---
## 0. Purpose
This is an **AI contract**, not a traditional design deck.
- Consistent brand across H5 / Mini Program / Web / App
- Stop random UI decisions
- Reuse components before inventing
- Shared language here; platform limits in `platform/*`
When uncertain: **DO NOT invent. ASK FIRST.** Consistency > creativity.
---
## 1. Design Philosophy
### Core values
| Value | UI implication |
|---|---|
| Simple | One job per section; short copy |
| Calm | Warm soft surfaces; low motion; no neon |
| Trustworthy | Clear hierarchy; disclaimer on reports |
| Professional | Stable tokens; no gaming chrome |
| Human-centered | Soft language; easy exit from paywalls |
| AI-first | Ask / chat are first-class patterns |
### Domain (psychology / wellness) — MUST
- Gentle self-understanding — not clinical hospital UI, not fortune-telling casino.
- Atmosphere: warm peach / coral wash → white content sheet.
- Unicode symbols (△ ☯ ◈) or SVG over emoji in chrome.
- Copy: friendly, clear, respectful, encouraging.
- **MUST NOT:** fear, guilt, fake urgency, medical cure claims, 吉凶祸福.
### MUST NOT create
- Excessive multi-stop gradients on chrome
- Neon, glow, dark-mode-by-default, purple-on-white “AI slop”
- Gaming HUD, particle spam, continuous decorative animation
- Random illustrations / emoji clusters
- Inconsistent spacing / one-off hex colors
- Dashboard clutter in home first viewport
---
## 2. Design Architecture
```
Foundation (tokens) → Components (catalog) → Platform implementation
```
AI MUST follow this order. Never invent page magic numbers or duplicate components.
---
## 3. Foundation — Design Tokens
All UI values MUST use tokens from `packages/ui` (or platform mapping of the same names).
Forbidden: `padding:17px; color:#2563eb; border-radius:13px;`
Required: `padding:var(--spacing-md); color:var(--color-primary); border-radius:var(--radius-md);`
If a token is missing: **ASK** or add it to `packages/ui/src/tokens.css` in the same change — do not hardcode.
Legacy `--yxg-*` remains valid; new code SHOULD prefer semantic names below.
---
## 4. Color System
Use only these semantic colors. Do not invent brand hues.
### Primary
| Token | Value | Use |
|---|---|---|
| `--color-primary` | `#E54D42` | CTA, brand, active tab |
| `--color-primary-hover` | `#D44338` | Hover / pressed |
| `--color-primary-soft` | `#FFE4E4` | Soft chip / Ask surface |
| `--color-primary-disabled` | `#F5B5B0` | Disabled primary |
Brand CTA gradient (only this one):
`linear-gradient(135deg, #FF7A6E, var(--color-primary))`
### Atmosphere
| Token | Value |
|---|---|
| `--color-bg-start` | `#FFD1C7` |
| `--color-bg-end` | `#FFC8B5` |
| `--color-bg-sheet` | `#FFF9F7` |
Do not replace with flat gray or purple gradients.
### Neutral
| Token | Value | Use |
|---|---|---|
| `--color-surface` | `#FFFFFF` | Cards, sheets, nav |
| `--color-text-primary` | `#333333` | Titles / body |
| `--color-text-secondary` | `#999999` | Subcopy |
| `--color-text-tertiary` | `#BBBBBB` | Meta |
| `--color-border` | `#F0F0F0` | Dividers |
| `--color-border-strong` | `#EEEEEE` | Inputs |
| `--color-input-bg` | `#FDFAF8` | Form fields |
### Domain accents (tint only — not global CTA)
| Token | Value | Feature |
|---|---|---|
| `--color-accent-gold` | `#C8923A` | Decode |
| `--color-accent-gold-soft` | `#FFF3D6` | Decode tile |
| `--color-accent-blue` | `#4A90E2` | Scale |
| `--color-accent-blue-soft` | `#E3EEFF` | Scale tile |
| `--color-accent-green` | `#5CB85C` | Companion / SolarTerm |
| `--color-accent-green-soft` | `#E0F6E4` | Companion tile |
| `--color-accent-orange` | `#E8985A` | Warm secondary |
| `--color-accent-purple` | `#8B5CF6` | Sparse only — never page theme |
### Status (only)
`success` · `warning` · `error` · `info`
Map: success≈green, warning≈orange/gold, error≈primary family, info≈blue.
### Forbidden
Neon / pure-black full-bleed / random Tailwind blue as brand / purple global theme.
---
## 5. Typography
Stack: `-apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", sans-serif`
Do not add Inter/Roboto/display fonts on product UI without ADR.
| Level | Size | Weight | Use |
|---|---|---|---|
| Display | 2832px | 700 | Brand 愈心谷 only |
| Heading 1 | 2022px | 700 | Page hero |
| Heading 2 | 1617px | 600700 | Section |
| Heading 3 | 15px | 600 | Card title |
| Body | 14px | 400 | Default |
| Body Small | 1213px | 400 | Secondary |
| Caption | 1011px | 400 | Tab / disclaimer |
No arbitrary sizes. Body line-height ≈ 1.61.7.
---
## 6. Spacing
Scale: **4 · 8 · 12 · 16 · 24 · 32 · 48 · 64**
| Token | px |
|---|---|
| `--spacing-2xs` | 4 |
| `--spacing-xs` | 8 |
| `--spacing-sm` | 12 |
| `--spacing-md` | 16 |
| `--spacing-lg` | 24 |
| `--spacing-xl` | 32 |
| `--spacing-2xl` | 48 |
| `--spacing-3xl` | 64 |
Forbidden: 13 / 18 / 27 / 35. Page pad default: 16.
---
## 7. Radius, shadow, width
| Token | Value | Use |
|---|---|---|
| `--radius-sm` | 10px | Back / small controls |
| `--radius-md` | 12px | Inputs / tiles |
| `--radius-lg` | 16px | Cards |
| `--radius-xl` | 1820px | Large sheets |
| `--radius-pill` | 999px | CTA capsule |
Shadows: `--shadow-card: 0 2px 10px rgba(0,0,0,.04)`; `--shadow-nav: 0 -2px 8px rgba(0,0,0,.03)`. No glow.
`--layout-max-user: 430px` · `--layout-nav-h: 56px`
---
## 8. Components
MUST reuse. Before creating: catalog → `src/components/` → extend.
No `SpecialButton` / `CustomButton2` / `NewCard`.
---
## 9. Layout Patterns
| Pattern | Screens |
|---|---|
| HomeWash | Brand + Decode + white sheet |
| List | Explore, orders |
| Detail | Report / Match |
| Form | Decode birthday, edit Profile |
| Profile | Mine / switch Profile |
| Settings | Account, privacy |
| AI Chat | Ask |
| Paywall | Membership / Unlock |
| Companion | SolarTerm + Mood |
Home first viewport: **brand · headline · Decode form · CTA**. No stats/promo clutter.
---
## 10. Interaction States
Network UI MUST have: Loading (skeleton) · Empty · Error (+ recovery) · Success · Disabled.
Paywall: free conclusion, lock reason/plan; no fake countdown.
---
## 11. Motion
Durations: **150 / 200 / 300ms**. Feedback only.
No continuous loops or decorative scroll animation.
---
## 12. Accessibility
Contrast for body text; touch ≥ 44px; no hover-only essentials; label interactive controls.
---
## 13. Brand Voice
温和、清晰、尊重。禁止恐吓 / 道德绑架 / 虚假倒计时.
Report/Ask: lifestyle disclaimer(非医疗、非算命). Labels follow `.ai/domain.md`.
---
## 14. Platforms
Shared language = this file. Limits = `platform/*`.
Priority: **H5 → Mini Program → Website → Flutter**.
---
## 15. Before Coding Checklist
- [ ] Catalog + components checked
- [ ] Correct `platform/*.md` read
- [ ] Tokens only
- [ ] Loading / empty / error
- [ ] Compliance copy if Report / Ask / Membership
- [ ] A11y (touch / contrast)
- [ ] No emoji chrome; no medical / 吉凶 wording
---
## 16. Final Rule
Uncertain → **ASK**. Do not invent colors, components, or layouts.
+38
View File
@@ -0,0 +1,38 @@
# Platform Contract — Flutter / Native App
Future client. Not in MVP scope unless task explicitly opens it.
Design language: [../design-system.md](../design-system.md) · Catalog names stay the same.
---
## Priority
**Performance > Native experience > Visual decoration**
---
## MUST
- Map tokens to `ThemeData` / design token classes — same hex and spacing scale.
- Native navigation patterns (Material/Cupertino as decided by ADR).
- Platform permissions (camera, photos, notifications) only with clear UX rationale.
- 60fps interactions; avoid heavy blur/shadow on low-end devices.
- Reuse catalog component names (`Button`, `ChatBubble`, `SubscriptionCard`…).
- Same compliance and domain copy rules.
---
## MUST NOT
- Invent a dark-neon “AI app” skin.
- Bypass API unlock/membership rules with local flags.
- Port Web DOM assumptions.
---
## Checklist
- [ ] Token theme 1:1 with `packages/ui`
- [ ] Catalog parity for screens in scope
- [ ] Permission + performance considered
- [ ] ADR if introducing Flutter stack officially
+47
View File
@@ -0,0 +1,47 @@
# Platform Contract — H5 (Mobile Web)
Primary shipping client: `apps/user-h5` (Vue 3 + Vite).
Design language: [../design-system.md](../design-system.md) · Components: [../component-catalog.md](../component-catalog.md)
---
## MUST
- Mobile-first; content column `max-width: var(--layout-max-user)` (430px), centered on large screens.
- Touch targets ≥ 44×44px.
- Prefer bottom actions (TabBar, AskInputBar, sticky CTA).
- Safe area: `env(safe-area-inset-bottom)` on TabBar / fixed footers.
- `user-scalable` / viewport per existing app shell; no desktop-only hover for essentials.
- Import tokens from `@yuxingu/ui` / `packages/ui` — no page-local brand hex.
- Data via `src/api``@yuxingu/sdk` only (no raw `fetch` in pages).
- Structure: `pages/` · `components/` · `layouts/` · `stores/` · `router/`.
- Loading / empty / error on every network view.
- Report / Decode / Ask: compliance disclaimer.
---
## MUST NOT
- Rely on hover tooltips for critical info.
- Use `window` APIs that break iOS WeChat/browser without fallback.
- Invent a second tab IA; tabs = Home / Explore / Ask / Companion / Mine.
- Grow Legacy root HTML (`yuxingu.html`, `pages/`) for new UI.
---
## Layout notes
- HomeWash: peach gradient body + Decode form + white ContentSheet.
- Secondary: TopBar + padded content.
- Keyboard: inputs must not hide primary CTA (scroll / visualViewport aware when needed).
---
## Checklist before Done
- [ ] Tokens only
- [ ] Catalog component reused or catalog updated
- [ ] 44px touch
- [ ] Safe area
- [ ] States + compliance if needed
- [ ] `npm run build:h5`
+47
View File
@@ -0,0 +1,47 @@
# Platform Contract — WeChat Mini Program
Client: `apps/mini-program`.
Design language shared with H5; **implementation is native mini-program**, not Vue SFC reuse.
Tokens: map `packages/ui` values into `app.wxss` / CSS variables supported by the base library — do not fork a second palette.
---
## MUST
- Use Mini Program lifecycle (`onLoad` / `onShow` / …) and `wx` APIs.
- Native navigation (`wx.navigateTo`, tabBar in `app.json`).
- Components under `components/`; pages call `services/*` only (same idea as H5 sdk).
- Support: share (`onShareAppMessage`), user authorization, payment flow when enabled.
- Touch ≥ 44px; rpx spacing aligned to 4/8/12/16… scale.
- Same IA tabs and domain copy rules as H5.
- Paywall / Membership decisions still from API — never local unlock only.
---
## MUST NOT
- `window` / `document` / DOM browser APIs.
- Import Vue SFCs from `user-h5` as runtime.
- Duplicate brand colors with new hex values.
- Build UGC广场 or Consult marketplace in MVP.
---
## Mapping
| H5 | Mini Program |
|---|---|
| Vue page | `pages/*` |
| Pinia | global / store pattern approved in playbook |
| `@yuxingu/sdk` | same package or thin `services` wrapper |
| CSS modules | `wxss` + shared token sheet |
---
## Checklist
- [ ] No browser-only APIs
- [ ] Tokens mapped 1:1
- [ ] Share / auth / pay paths considered
- [ ] Catalog names reused
+44
View File
@@ -0,0 +1,44 @@
# Platform Contract — Website (Desktop / Marketing Web)
Future or secondary surfaces (landing, SEO pages, admin beyond mobile shell).
Brand tokens identical to [../design-system.md](../design-system.md).
---
## MUST
- SEO basics: title / description / semantic headings on marketing pages.
- Keyboard navigation and visible focus for interactive controls.
- Hover states allowed as **enhancement**; core actions still work without hover.
- Large screens: may use sidebar, table, multi-column — do not ship desktop-only flows that leave mobile broken if the same app is responsive.
- Accessibility: contrast, labels, skip/focus order.
- Admin (`apps/admin-h5`): denser List/Table OK; still use tokens (primary coral, not random admin blue).
---
## MUST NOT
- Purple SaaS gradient landing that ignores 愈心谷 peach/coral brand.
- Heavy dashboard chrome on consumer marketing hero (see design-system home budget).
- Medical / 吉凶 claims in SEO copy.
---
## Breakpoints
| Name | Guide |
|---|---|
| Mobile | &lt; 768px — follow H5 patterns |
| Tablet | 7681024px — adapt columns, keep touch sizes |
| Desktop | &gt; 1024px — sidebar / multi-column allowed |
Do not merely scale desktop UI down to mobile.
---
## Checklist
- [ ] Tokens + brand voice
- [ ] Keyboard / focus
- [ ] Responsive behavior explicit
- [ ] SEO for public pages
+65
View File
@@ -0,0 +1,65 @@
# Domain Language — Ubiquitous Terms
Use ONLY these words in code, API, UI copy (Chinese labels noted).
Do not invent synonyms (Customer / Client / Account) unless added here via ADR.
**Bounded contexts / aggregates / ER:** [domain/domain-map.md](domain/domain-map.md)
**Product feature tree:** [product/feature-map.md](product/feature-map.md)
## Identity & access
| Term | Meaning | Not |
|---|---|---|
| **Visitor** | 未登录访客;可有匿名 device id | Guest(勿混用) |
| **User** | 已注册主体(有 user id | Customer / Client |
| **Member** | 同 User:已注册用户的业务称呼;代码字段优先 `user` | — |
| **VIP** | 付费会员期内的 Usermembership active | Member(勿把所有注册用户叫 VIP) |
| **Session** | 登录态 / token 会话 | — |
## Commerce
| Term | Meaning |
|---|---|
| **Subscription** | 会员订阅计划(月/季/年) |
| **Membership** | 用户当前会员权益状态(是否 VIP、到期时间、额度) |
| **Order** | 支付订单(报告解锁或订阅) |
| **Payment** | 一笔支付尝试 / 渠道回调结果 |
| **Refund** | 退款记录 |
| **Unlock** | 对某 Report 的购买解锁(非 VIP 也可单次解锁) |
## Profile & content
| Term | Meaning |
|---|---|
| **Profile** | 档案:自己或 TA 的生日等输入 |
| **Self Profile** | relation = self |
| **Other Profile** | relation = otherTA |
| **Decode** | 愈心解码报告(数字性格 + 体质建议) |
| **Report** | 统称:Decode / Match / 尊享报告等可交付物 |
| **Match** | 双人/家庭契合度报告 |
| **Scale** | 心理量表 |
| **ScaleResult** | 量表作答与计分结果 |
## Retention & AI
| Term | Meaning |
|---|---|
| **Companion** | 陪伴域:节气、心情 |
| **SolarTerm** | 二十四节气内容单元 |
| **Mood** | 每日心情打卡 |
| **Ask** | 「问」能力:基于 Profile 的解读对话 |
| **Consult** | 真人顾问咨询(后置) |
## Platform
| Term | Meaning |
|---|---|
| **user-h5** | 用户 H5 客户端 |
| **mini-program** | 微信小程序客户端 |
| **api** | Go 后端唯一服务 |
| **Legacy** | 根目录旧静态原型,只读 |
## Naming in code
- Go packages / JSON: `user`, `profile`, `report`, `order`, `membership`, `scale`
- Never: `customer`, `client` (except HTTP client), `account` (unless wallet later + ADR)
+6
View File
@@ -0,0 +1,6 @@
# Domain docs
| File | Purpose |
|---|---|
| [../domain.md](../domain.md) | Ubiquitous language — terms only |
| [domain-map.md](domain-map.md) | Bounded contexts, aggregates, ER sketch |
+183
View File
@@ -0,0 +1,183 @@
# Domain Map — 愈心谷(DDD 视角)
给后端 / DB / OpenAPI / SDK 用的**能力域与实体图**。
词汇以 [../domain.md](../domain.md) 为准;产品范围以 [../product/feature-map.md](../product/feature-map.md) 为准。
竞品能力对照:[../product/cece-feature-map.md](../product/cece-feature-map.md)。
AI 生成表结构或 API 时:先落本图中的 Context / Aggregate,再写 migration;禁止发明未列出的聚合根名。
---
## 1. Bounded Contexts
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Identity │──▶│ Profile │──▶│ Discovery │
│ (User) │ │ Life Archive│ │ Decode/Scale│
└─────────────┘ └──────┬───────┘ └──────┬──────┘
│ │
▼ ▼
┌──────────────┐ ┌─────────────┐
│ Relationship │ │ Ask │
│ Match │ │ Companion │
└──────┬───────┘ └──────┬──────┘
│ │
▼ ▼
┌─────────────────────────────────┐
│ Commerce │
│ Subscription / Order / Unlock │
└─────────────────────────────────┘
┌──────────────┼──────────────┐
▼ ▼ ▼
ContentFeed GrowthShare Consult(*)
(* later)
```
| Context | 职责 | MVP |
|---|---|---|
| **Identity** | Visitor/User/Session | Yes |
| **Profile** | Self/Other 生命档案 | Yes |
| **Discovery** | Decode、Scale、Report 生成 | Yes |
| **Relationship** | Match | Yes |
| **Ask** | 档案上下文对话、额度 | Skeleton |
| **Companion** | SolarTerm、Mood | Skeleton |
| **Commerce** | Subscription、Membership、Order、Unlock、Payment | Yes (mock) |
| **Content** | Feed 配置 | Static OK |
| **Growth** | Share 卡片元数据 | Minimal |
| **Consult** | 真人顾问 Marketplace | No |
| **Recommendation** | 推荐 | V1 rules |
---
## 2. Aggregates & Entities(命名强制)
### Identity
| Type | Name | Notes |
|---|---|---|
| Aggregate | **User** | 注册主体 |
| Entity | Session | token 会话 |
| Entity | DeviceIdentity | Visitor 匿名 |
### Profile(生命档案)
| Type | Name | Notes |
|---|---|---|
| Aggregate | **Profile** | `relation`: self \| other |
| VO | BirthInput | datetime/place optional later |
| VO | RelationType | partner/family/friend/… |
### Discovery
| Type | Name | Notes |
|---|---|---|
| Aggregate | **Report** | type: decode \| match \| … |
| Domain Svc | DecodeEngine | 可复算;结果入 Report |
| Aggregate | **Scale** | 量表定义 |
| Entity | ScaleQuestion | |
| Aggregate | **ScaleResult** | 作答 + 计分 |
### Relationship
| Type | Name | Notes |
|---|---|---|
| Aggregate | **Match** | 引用两个 Profile;产出 Report 或嵌入 |
### Ask / Companion
| Type | Name | Notes |
|---|---|---|
| Aggregate | **AskThread** | 挂 profile_id |
| Entity | AskMessage | role user/assistant |
| Entity | AskQuota | 与 Membership 联动 |
| Aggregate | **Mood** | 日维度打卡 |
| Read Model | **SolarTerm** | 日历内容;可配置表 |
### Commerce
| Type | Name | Notes |
|---|---|---|
| Aggregate | **Subscription** | 计划 SKU |
| Aggregate | **Membership** | 用户权益状态 |
| Aggregate | **Order** | 订阅或 Unlock |
| Entity | Payment | mock / 渠道 |
| Entity | Unlock | order → report 解锁 |
### Content / Growth(薄)
| Type | Name | Notes |
|---|---|---|
| Entity | FeedItem | 运营配置 |
| VO | SharePayload | 分享卡字段 |
### ConsultLater
| Type | Name | Notes |
|---|---|---|
| Aggregate | Consultant | |
| Aggregate | ConsultOrder | |
| Entity | ConsultSession | |
---
## 3. 关键关系(ER 草图)
```
User 1──* Profile
Profile 1──* Report
Profile 1──* AskThread
User 1──* ScaleResult
User 1──0..1 Membership
User 1──* Order
Order 0..1── Unlock ──▶ Report
Profile ── Match ── Profile
User 1──* Mood
```
权益规则:**Membership / Unlock 只由服务端判定**;客户端不可信任。
---
## 4. Context → 代码落点
| Context | Go | H5 |
|---|---|---|
| Identity | `internal/service/user` | login / mine |
| Profile | `service/profile` | decode form, mine |
| Discovery | `service/report`, `service/scale` | decode, explore, report |
| Relationship | `service/match` | match |
| Ask | `service/ask` | ask tab |
| Companion | `service/companion` | companion tab |
| Commerce | `service/order`, `membership` | paywall, mine |
包名只用 `domain.md` 词汇:`user` `profile` `report` `order` `membership` `scale` `ask` `mood`
---
## 5. 测测域 → 愈心谷域 映射
| 测测概念 | 愈心谷 |
|---|---|
| 星盘档案 | **Profile**(生日+体质相关输入) |
| 测测 AI | **Ask** |
| 真人 1v1 | **Consult**(后置) |
| MBTI 等 | **Scale** |
| 缘分合盘 | **Match**(合规叙事) |
| 今日运势 | **SolarTerm** + 生活建议(替换) |
| 会员 | **Subscription / Membership** |
| AI 玩法广场 | **[No] MVP** |
| 心情打卡 | **Mood** |
| 沙盘/心情小镇 | **[No]** |
---
## 6. 生成顺序(给 AI
1. 改范围 → 更新 `product/feature-map.md` MVP 标记
2. 新实体 → 本文件 + `domain.md` 词条(若新词)
3. migration → `playbooks/new-table.md`
4. API → `playbooks/add-api.md` + OpenAPI
5. 页面 → `playbooks/new-page.md` + design contract
下一步可选:单独 `apps/docs/erd.md` 或 migrations 初稿(本任务不强制)。
+25
View File
@@ -0,0 +1,25 @@
{
"success_example": {
"code": 0,
"message": "success",
"data": {
"summary": "简版结论占位",
"profile_id": "p_123"
}
},
"error_example": {
"code": 30001,
"message": "invalid birth date"
},
"list_example": {
"code": 0,
"message": "success",
"data": {
"list": [{ "slug": "mbti", "name": "MBTI" }],
"total": 1,
"page": 1,
"page_size": 20
}
},
"_comment": "Never use {success:true} or {ok:true} as root."
}
+54
View File
@@ -0,0 +1,54 @@
//go:build ignore
// EXAMPLE — reference shape for AI. Not compiled into apps/api.
package examples
import (
"context"
"net/http"
"github.com/gin-gonic/gin"
)
type apiBody struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
type DecodeInput struct {
Year int
Month int
Day int
}
type DecodeOutput struct {
Summary string `json:"summary"`
}
type DecodeService interface {
Decode(ctx context.Context, in DecodeInput) (*DecodeOutput, error)
}
type DecodeHandler struct {
Svc DecodeService
}
// Decode handles POST /api/v1/reports/decode
func (h *DecodeHandler) Decode(c *gin.Context) {
var req struct {
Year int `json:"year" binding:"required"`
Month int `json:"month" binding:"required"`
Day int `json:"day" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, apiBody{Code: 10000, Message: "invalid request"})
return
}
out, err := h.Svc.Decode(c.Request.Context(), DecodeInput(req))
if err != nil {
c.JSON(http.StatusBadRequest, apiBody{Code: 30001, Message: err.Error()})
return
}
c.JSON(http.StatusOK, apiBody{Code: 0, Message: "success", Data: out})
}
+29
View File
@@ -0,0 +1,29 @@
//go:build ignore
// EXAMPLE — reference shape for AI. Not compiled into apps/api.
package examples
import (
"context"
"fmt"
)
type DecodeRepo interface {
SaveDecode(ctx context.Context, userID string, summary string) error
}
type DecodeServiceImpl struct {
Repo DecodeRepo
}
func (s *DecodeServiceImpl) Decode(ctx context.Context, in DecodeInput) (*DecodeOutput, error) {
if in.Year < 1900 || in.Month < 1 || in.Month > 12 || in.Day < 1 || in.Day > 31 {
return nil, fmt.Errorf("invalid birth date")
}
// engine would run here
summary := "简版结论占位"
if err := s.Repo.SaveDecode(ctx, "user-from-ctx", summary); err != nil {
return nil, fmt.Errorf("save decode: %w", err)
}
return &DecodeOutput{Summary: summary}, nil
}
+39
View File
@@ -0,0 +1,39 @@
//go:build ignore
// EXAMPLE — table-driven unit test shape.
package examples
import "testing"
func TestClampBirthMonth(t *testing.T) {
tests := []struct {
name string
month int
wantErr bool
}{
{name: "ok", month: 6, wantErr: false},
{name: "zero", month: 0, wantErr: true},
{name: "thirteen", month: 13, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateMonth(tt.month)
if (err != nil) != tt.wantErr {
t.Fatalf("validateMonth(%d) err=%v wantErr=%v", tt.month, err, tt.wantErr)
}
})
}
}
func validateMonth(m int) error {
if m < 1 || m > 12 {
return errInvalid
}
return nil
}
var errInvalid = errString("invalid")
type errString string
func (e errString) Error() string { return string(e) }
+93
View File
@@ -0,0 +1,93 @@
# File Map — Who Owns What
## apps/api
```
apps/api/
cmd/server/ # main only: wire deps, start HTTP
internal/
handler/ # HTTP bind/unbind, validate input, call service interfaces
service/<domain>/ # business rules, transactions orchestration
repository/ # SQL / DB access only
model/ # DB structs / domain structs (no HTTP types leakage preferred)
middleware/ # auth, request id, recovery helpers
config/ # env config
pkg/ # small reusable libs (e.g. response envelope)
migrations/ # schema versions
```
### Forbidden placements
| Wrong | Right |
|---|---|
| SQL in `handler/` | `repository/` |
| gin.Context in `repository/` | keep HTTP out of repo |
| Business unlock rules only in UI | `service/` + persist |
| Fat `pkg/utils` | domain package or focused pkg |
## apps/user-h5
```
src/
pages/ # route screens
components/ # reusable UI
api/ # thin wrappers → @yuxingu/sdk
stores/ # pinia
hooks/ # composables
router/
layouts/
assets/
```
No raw `fetch` in `pages/`.
## packages
| Package | Owns |
|---|---|
| `sdk` | HTTP client + adapters |
| `types` | Shared TS domain types |
| `utils` | Pure helpers |
| `ui` | CSS tokens |
## .ai/
Rules, ADR, patterns, examples, playbooks, checklists. Not runtime code.
### .ai/product/ & .ai/domain/
| Path | Owns |
|---|---|
| `product/feature-map.md` | 愈心谷 L0/L1/L2 + MVP 标记 |
| `product/cece-feature-map.md` | 测测竞品合并 Feature Tree |
| `domain/domain-map.md` | Bounded contexts / aggregates / ER |
| `domain.md` | Ubiquitous terms only |
### .ai/design/
| Path | Owns |
|---|---|
| `design-system.md` | Tokens, color, type, spacing, motion, voice |
| `component-catalog.md` | Allowed reusable UI components |
| `platform/*.md` | H5 / mini-program / website / Flutter limits |
Runtime CSS tokens: `packages/ui/src/tokens.css` (must stay aligned with design-system).
## apps/docs/
Product / business docs (not engineering rules):
| Path | Owns |
|---|---|
| `README.md` | Reading order |
| `analysis/` | Competitor teardowns |
| `prd-mvp.md` | MVP scope & acceptance |
| `business-model.md` | Revenue layers |
| `product-roadmap.md` | Phased vertical slices |
| `adr/` | Optional business-facing ADRs |
Engineering standards live in `.ai/` only; `apps/docs/standards/*` is deprecated.
## Legacy (do not extend)
Root `yuxingu.html`, `pages/`, `css/`, `js/`, `server.py`.
+37
View File
@@ -0,0 +1,37 @@
# Forbidden — Never
AI obeys NEVER rules strictly.
## Code
- Never use `panic` on request paths.
- Never ignore errors (`_ = err` on important paths).
- Never create circular dependencies.
- Never put SQL in handlers.
- Never put `gin.Context` in repositories.
- Never use package-level mutable globals for request state.
- Never use `SELECT *` in new SQL.
- Never introduce `any` casually in TypeScript.
- Never put `fetch` directly in Vue pages.
## API / data
- Never invent response shapes other than `{code,message,data}`.
- Never use POST for pure read/query.
- Never skip migration when schema changes.
- Never hard-delete user PII without explicit task (use soft delete).
## Security / deploy
- Never hardcode passwords, tokens, or secrets.
- Never commit `.env` or private keys.
- Never use Docker image tag `latest` in production.
- Never log full birthday + answers payloads casually.
## Product / process
- Never invent medical efficacy or 吉凶祸福 copy.
- Never reverse an Accepted ADR without a new ADR + approval.
- Never modify files outside the current task.
- Never extend Legacy root HTML unless the task is migration.
- Never guess requirements — ASK FIRST.
+14
View File
@@ -0,0 +1,14 @@
# Pattern: CRUD slice
For a resource `Foo`:
1. Migration `foo` table (`id, created_at, updated_at, deleted_at`, …)
2. `model.Foo`
3. `repository` methods: Get / List / Create / Update / SoftDelete
4. `service` with authz + validation
5. `handler` REST routes
6. OpenAPI paths
7. SDK methods + types
8. UI only if user-facing
List endpoints always paginate (`page`, `page_size`, `total`).
+37
View File
@@ -0,0 +1,37 @@
# Pattern: Handler
## Responsibility
HTTP only: bind JSON/query → validate → call service interface → map errors to envelope.
## Shape
```go
type ReportService interface {
Decode(ctx context.Context, in DecodeInput) (*DecodeOutput, error)
}
type ReportHandler struct {
svc ReportService
}
func (h *ReportHandler) Decode(c *gin.Context) {
var req DecodeRequest
if err := c.ShouldBindJSON(&req); err != nil {
response.Fail(c, 400, 10000, "invalid request")
return
}
out, err := h.svc.Decode(c.Request.Context(), toInput(req))
if err != nil {
// map domain errors → codes
response.Fail(c, 400, 30001, err.Error())
return
}
response.OK(c, out)
}
```
## Never
- SQL here
- Business unlock math here (belongs service)
+13
View File
@@ -0,0 +1,13 @@
# Pattern: JWT / Bearer
## Middleware
1. Read `Authorization: Bearer <token>`
2. Parse/verify
3. Put `user_id` into context
4. Reject with code in 1xxxx if missing/invalid
## Service
Always take `userID` from context for mutating ops.
Never trust body `user_id` from client for ownership.
+22
View File
@@ -0,0 +1,22 @@
# Pattern: Pagination
## Query
`?page=1&page_size=20`
Defaults: page=1, page_size=20, max page_size=100.
## Response data
```json
{
"list": [],
"total": 0,
"page": 1,
"page_size": 20
}
```
## SQL
`LIMIT $n OFFSET $m` with bound params. Always return `total` via `COUNT(*)` (or approximate only with ADR).
+24
View File
@@ -0,0 +1,24 @@
# Pattern: Repository
## Responsibility
Persistence only. Parameterized SQL. Map rows ↔ model.
## Shape
```go
func (r *ReportRepository) SaveReport(ctx context.Context, m *model.Report) error {
const q = `INSERT INTO report (id, user_id, kind, payload, created_at, updated_at)
VALUES ($1,$2,$3,$4,now(),now())`
_, err := r.db.ExecContext(ctx, q, m.ID, m.UserID, m.Kind, m.Payload)
if err != nil {
return fmt.Errorf("insert report: %w", err)
}
return nil
}
```
## Never
- `SELECT *` in new code
- Business policy (VIP checks) here — return data, let service decide
+31
View File
@@ -0,0 +1,31 @@
# Pattern: Service
## Responsibility
Business rules, authorization, orchestration, transactions.
## Shape
```go
type ReportRepo interface {
SaveReport(ctx context.Context, r *model.Report) error
}
type ReportService struct {
repo ReportRepo
}
func (s *ReportService) Decode(ctx context.Context, in DecodeInput) (*DecodeOutput, error) {
if err := in.Validate(); err != nil {
return nil, fmt.Errorf("validate decode: %w", err)
}
// rules / engine
// persist via repo
return out, nil
}
```
## Never
- Import `gin`
- Bypass repo with ad-hoc SQL drivers scattered around
+19
View File
@@ -0,0 +1,19 @@
# Playbook: Add API
Use when: “新增xxx接口”
## Steps
1. **OpenAPI** — add path to `proto/openapi.yaml`
2. **Migration** — if new/changed table (`apps/api/migrations/`)
3. **Model**`internal/model`
4. **Repository** — SQL only
5. **Service** — business + authz
6. **Handler** — bind + envelope; interface at handler
7. **Wire** — register route in `cmd/server` or router file
8. **Test** — at least service/engine unit test if logic-heavy
9. **SDK/types** — update `packages/sdk` + `packages/types` if clients need it
10. **Commands**`go test ./...`, hit with curl
11. **Review + DoD + checklist/feature.md**
Follow patterns: `handler.md` `service.md` `repository.md` `pagination.md`.
+14
View File
@@ -0,0 +1,14 @@
# Playbook: Login / Auth
## Steps
1. Cite ADR-0004
2. Define Visitor vs User in API behavior (`.ai/domain.md`)
3. Issue Bearer token; document in OpenAPI
4. Middleware extracts `user_id`
5. Persist session/user as designed (Postgres MVP; Redis deferred)
6. H5: store token via adapter (`localStorage` key `yxg_token`)
7. SDK `getToken` wired
8. Tests: invalid token / expired / ownership
9. Security review checklist
10. Never accept `X-User-Id` alone as auth
+18
View File
@@ -0,0 +1,18 @@
# Playbook: New H5 Page
Use when: “新增页面”
## Steps
1. Confirm IA tab vs secondary page (`.ai/ui.md`)
2. Read `.ai/design/design-system.md` + `component-catalog.md` + `design/platform/h5.md`
3. Reuse catalog components; update catalog if adding a new one
4. Add route in `apps/user-h5/src/router`
5. Add `pages/XxxPage.vue` (PascalCase); tokens only (no raw brand hex)
6. Extract components if file approaches 300400 lines
7. Data via `src/api``@yuxingu/sdk` only
8. Use domain words from `.ai/domain.md`
9. Loading / empty / error states
10. Compliance copy if report-like
11. `npm run build:h5`
12. Review + checklist/feature.md
+14
View File
@@ -0,0 +1,14 @@
# Playbook: New Table
Use when: “新建表 / 加字段”
## Steps
1. Name with `snake_case` (`.ai/database.md` + `.ai/domain.md`)
2. Columns include `id, created_at, updated_at, deleted_at`
3. Write migration Up (+ Down)
4. Index FKs
5. Update `model` + repository
6. Never ship app code that queries columns not migrated
7. Document in PR
8. Review (Deployment + Docs items)
+14
View File
@@ -0,0 +1,14 @@
# Playbook: Payment / Unlock / Subscription
## Steps
1. Terms: Order, Payment, Unlock, Subscription, Membership, VIP (`.ai/domain.md`)
2. Server creates Order with amount/currency/product ref
3. Client never sets final price unilaterally
4. Payment callback verifies signature + idempotency
5. On success: grant Membership or Unlock in service transaction
6. Report access checks Membership/Unlock server-side every time
7. Migration for `payment_order` / related tables
8. Tests: double callback, wrong amount, replay
9. No secrets in frontend
10. Feature checklist + security review
+12
View File
@@ -0,0 +1,12 @@
# Product docs for AI agents
| File | Audience | Purpose |
|---|---|---|
| [STRATEGY.md](STRATEGY.md) | All agents | **执行优先级**:先测测 parityVision v1 已封存 |
| [feature-map.md](feature-map.md) | PRD / H5 / API | 愈心谷差异化能力树(Design Vision v1 |
| [cece-feature-map.md](cece-feature-map.md) | Competitor / parity | 测测 Feature Tree — 下一版对齐主参考 |
| [../domain/domain-map.md](../domain/domain-map.md) | Backend / DB / OpenAPI | Bounded contexts & entities |
| [../domain.md](../domain.md) | All code | Ubiquitous language (terms only) |
Product narrative docs (human PRD): `apps/docs/`.
**冲突时:** `STRATEGY.md` 的 parity 执行 > Vision v1 创新项。
+32
View File
@@ -0,0 +1,32 @@
# Product Strategy Snapshot
## Sealed design (this repo state)
Documented vision: **愈心谷差异化** — 数字性格 + 中医体质 + 关系档案 + 节气,学测测飞轮但替换运势主叙事。
Canonical docs at seal time:
- `product/feature-map.md` — 愈心谷能力树(含 MVP 标记)
- `product/cece-feature-map.md` — 测测竞品树
- `domain/domain-map.md` — 领域模型
- `apps/docs/prd-mvp.md` · `business-model.md` · `product-roadmap.md`
- `.ai/design/*` — Design System Contract
Treat the above as **Design Vision v1(已封存)** — 可对照、可回退,不作为下一迭代的强制做完清单。
---
## Next build direction(执行优先)
**先出一版和测测结构类似的产品,不要一上来就创新。**
| 原则 | 含义 |
|---|---|
| IA 对齐测测 | 首页发现 · 问(AI)· 在线/咨询位 · 消息或可后置 · 我的 |
| 能力对齐测测漏斗 | 测评拉新 → 档案 → AI 问 → 会员 → 咨询占位 |
| 叙事可先「泛心理 + 星座/性格」 | 体质/节气差异化后置,不阻塞首版 |
| 不做冷启动重资产 | 不做达人双边冷启动、不做硬件、不做 UGC 玩法广场首版 |
差异化 Vision v1 在首版跑通测测式漏斗后再渐进引入(Decode 体质、节气陪伴等)。
执行时以即将撰写的 **Cece-parity PRD / feature-map-v0** 为准;冲突时:**parity 执行 > Vision v1 创新项**。
+307
View File
@@ -0,0 +1,307 @@
# 测测 App — Feature Map(竞品 · 合并视角)
来源:[人人都是产品经理 · 测测深度体验](https://www.woshipm.com/evaluating/6391148.html) + 公开产品形态 / 行业常见能力。
用途:竞品分析与 AI 产品设计对照。**不代表**测测未公开内部功能;版本会变。
视角说明:
| 视角 | 回答的问题 | 本文件位置 |
|---|---|---|
| L0 Product IA | 用户打开 App 看到什么、怎么付费 | §1 L0 |
| L1 Capability | 系统背后有哪些能力域 | §2 挂在各入口下 / §3 横切 |
| 演进 | 工具 → AI 顾问 → Life OS | §4 |
愈心谷落地地图见 [feature-map.md](feature-map.md)。领域实体见 [../domain/domain-map.md](../domain/domain-map.md)。
---
## §0 一级能力域总览(Domain 视角)
```
测测能力域
├── 1. 用户体系
├── 2. 首页与内容分发
├── 3. AI 智能助手
├── 4. 测试与测算
├── 5. 星座体系
├── 6. 命理体系
├── 7. 塔罗体系
├── 8. 情感关系分析
├── 9. 心理与自我探索
├── 10. 社区生态
├── 11. 专家咨询
├── 12. 内容体系
├── 13. 会员与商业化
├── 14. 用户增长
└── 15. 数据与推荐系统
```
演进增量(行业方向,非全部已上线):人生档案 / AI Agent / 情绪 OS / 梦境 / 冥想 / 中医体质 / 易经决策 / 多模态 / 长期成长模型。
---
## §1 L0 — App 信息架构(用户路径)
```
打开 App
→ 首页发现与激活
→ 问(AI 战略入口)
→ 在线(真人 Marketplace
→ 消息(关系与通知)
→ 我的(资产 / 会员)
横切:增长运营 · 集团生态
```
```
测测 App
├── 首页
├── 消息
├── 问
├── 在线
├── 我的
├── 增长运营
└── 集团生态
```
---
## §2 L0 × L1 × L2 — 合并功能树
### 1. 首页(发现与激活中心)
#### 1.1 用户建档 → 生命档案系统
| 二级 | 三级 |
|---|---|
| 1.1.1 创建本人档案 | 出生日期 / 时间 / 地点 / 性别 |
| 1.1.2 创建关系档案 | 伴侣 / 家人 / 朋友 / 暗恋对象等 |
| 1.1.3 档案管理 | 编辑 / 删除 / 多档案切换 / AI 关联分析 |
| 1.1.4 兴趣与状态标签 | 爱情·事业·财富·健康·性格·家庭;情感/职业状态 |
#### 1.2 工具入口宫格(前台)↔ 能力归类(后台)
| 前台入口 | 归属能力域 |
|---|---|
| I人E人 / MBTI | 心理测评 / 测试系统 |
| 星座 / 星盘 | 星座体系 |
| 缘分合盘 | 情感关系 + 星座 |
| 沙盘 | 心理沉浸工具 |
| 陪伴小星 | AI 陪伴 |
| 倾诉 | 咨询 / AI 入口 |
| 商城 | 商业化 |
| AI 玩法广场 | 内容生态 · GPT Store 型 |
| 更多 | 收纳扩展 |
#### 1.3 首页推荐与信息流
- 今日运势 / 热门测试 / AI 入口 / 专家推荐 / 热门文章 / 社区动态
- 文章 · 视频 · 故事 · 达人内容 · AI 生成内容 · 个性推荐
#### 1.4 个性化推荐
- 按生日 / 兴趣 / 历史行为 / 付费意愿推荐
#### 1.5 AI 玩法广场(≈ GPT Store + 传播)
- 玩法模板 → Prompt 应用 → 用户/达人创建 AI 小应用 → 热度榜 → 裂变
- 示例形态:SBTI、答案之书、三生三世你和 Ta、灵魂伴侣等
#### 1.6 沉浸体验入口
- 3D 心理沙盘(投射分析)
- AI 心情小镇入口
---
### 2. 消息(互动与触达)
| 二级 | 三级 |
|---|---|
| 2.1 AI 消息 | 会话提醒、未读 AI 对话 |
| 2.2 达人消息 | 咨询会话、达人回复 |
| 2.3 社区互动 | 赞评关私信通知 |
| 2.4 系统通知 | 公告、合规、功能 |
| 2.5 商业通知 | 会员到期、订单、活动 |
---
### 3. 问(核心战略 · AI Life Assistant
实测:底部中央「问」Tab → 测测 AI;顶栏「测测AI ‖ 真人1v1」。
#### 3.1 AI 人格层
- 普通助手 / 情感陪伴 / 心理向疏导 / 星盘专家向 / 塔罗向 / 人生顾问
- 报道中的灵犀 / 小智:更接近模式或子场景,非并列 Tab 级产品
#### 3.2 AI 聊天场景
- 一般聊天 · 情感倾诉 · 人生建议 · 性格分析 · 梦境解析 · 星座咨询 · 命理解读
#### 3.3 AI 上下文层(差异化)
- 当前用户 → 生命档案 → 关系档案 → 历史对话 → 情绪轨迹 → 长期记忆
- UI:星盘维度 · 对象切换(自己/TA)· 深度思考 · 灵魂伴侣子入口
#### 3.4 AI 能力层(底层)
- LLM(心元等)· 心理知识库 · 星盘计算 · 测算模型 · 测试模型 · 推荐
#### 3.5 AI 报告生成
- 性格 / 爱情 / 职业 / 财富 / 综合人生报告
#### 3.6 AI 商业层
- 免费次数 → 会员扩容 → 高级模型/深度思考 → 转真人专家
#### 3.7 AI 心情小镇等沉浸
- 多虚拟倾诉师人设 · OCR/情感识别 · 角色陪伴
#### 3.8 已知能力缺口(公开评价)
- 偏被动响应(少主动触达)
- 跨会话长期记忆不足
- 引导问题偏运势,易被感知为「算命 AI」
---
### 4. 在线(真人 Marketplace
```
达人供应 → 平台撮合 → 交易 → 评价 → 复购 / 分佣
```
| 二级 | 三级 |
|---|---|
| 4.1 专家类型 | 星座专家 · 塔罗师 · 命理师 · 心理/情感达人 |
| 4.2 供给运营 | 达人资料 · 审核 · 培训激励(达人版工具) |
| 4.3 咨询流程 | 列表 → 预约 → 支付 → 文字/语音/连麦 → 评价 |
| 4.4 撮合与分佣 | 推荐排序 · 平台抽成 |
---
### 5. 我的(用户资产 → Life Profile
| 二级 | 三级 |
|---|---|
| 5.1 账号 | 手机 / 微信 / Apple · 游客升级 |
| 5.2 生命档案资产 | 本人档案 · 关系档案 · 编辑切换 |
| 5.3 测试与报告资产 | 测试记录 · 报告库 · 收藏 |
| 5.4 AI 资产 | 对话历史 · AI 报告 |
| 5.5 会员与订单 | 订阅状态 · 解锁记录 · 咨询订单 |
| 5.6 行为画像沉淀 | 浏览 / 测试 / 收藏 / 咨询记录 |
---
### 6. 增长运营(横切)
| 二级 | 三级 |
|---|---|
| 6.1 分享裂变 | 测试结果卡 · 邀请好友 · 社交传播 |
| 6.2 裂变引擎(产品逻辑) | 结果分享 → 好友进入 → 建档 → 再传播 |
| 6.3 内容获客 | SEO / 搜索 → 测试 → 注册 → 会员 |
| 6.4 激励 | 签到 · 积分 · 等级 · 勋章 |
| 6.5 广告 | 曾有;主动压缩干扰广告 |
| 6.6 品牌 | 创始人/媒体露出;少大规模买量 |
---
### 7. 集团生态(Business Layer
| 二级 | 三级 |
|---|---|
| 7.1 C 端 App | 测测主站 |
| 7.2 达人平台 | 测测达人版 |
| 7.3 教育延伸 | 快乐测测 |
| 7.4 B 端 | 企业 EAP · 校园心理健康 |
| 7.5 硬件 | 巴布家庭陪伴机器人(买断 + 模型协同) |
| 7.6 模型底座 | 心元大模型备案与训练数据飞轮 |
---
## §3 能力域详表(便于对照数据库 / 模块)
### A. 测试系统
- **性格**:MBTI · 九型 · 性格/优势/弱点画像
- **情感**:恋爱人格 · 伴侣匹配 · 关系状态 · 分手/婚恋向
- **心理**:情绪 · 压力 · 焦虑 · 自我探索 · 心理画像
- **趣味**:灵魂动物 · 前世 · 小游戏 · 趣味问答
### B. 星座体系
- 十二星座 · 星盘 · 上升/月亮 · 行星分析
- 匹配:恋爱/友情/婚姻指数
- 日运/周运/月运/年运
### C. 命理体系
- 八字:四柱 · 五行 · 十神 · 格局 · 大运 · 流年
- 紫微:命盘 · 十二宫 · 主星 · 流年
- 姓名/五格 · 风水建议
### D. 塔罗体系
- 抽牌:单牌 · 三牌 · 爱情/事业阵 · 趋势
- AI 解读:牌义 · 组合 · 行动建议 · 情绪支持
### E. 情感关系
- 恋爱分析:双人星盘 · 合婚 · 性格匹配 · 相处建议
- 关系管理:记录伴侣 · 关系变化 · 重要日期 · 情绪记录
### F. 心理成长
- 自我探索:性格 · 原生家庭 · 价值 · 内在需求
- 情绪管理:记录 · 分析 · 安慰陪伴 · 放松
- 成长计划:目标 · 每日练习 · 打卡 · 成长报告
- 沉浸:沙盘 · 心情小镇
### G. 社区生态
- 内容社区:发帖评论赞藏分享
- 用户关系:关注粉丝私信群组
- 话题:星座讨论 · 情感故事 · 测试分享 · AI 内容
### H. 内容体系
- 文章:星座/情感/心理/命理
- 视频:短视频 · 直播 · 课程
### I. 商业化
- 会员:月/季/年;权益含完整报告、AI 次数、专属内容、去广告等
- 增值:单次报告 · 真人咨询 · 课程 · 商城
### J. 数据与推荐
- 数据:行为 · 情绪 · 测试 · 对话
- 推荐:内容 · 测试 · 专家 · 商品
---
## §4 产品演进阶梯(分析用)
```
测测 1.0 测试工具集合
测测 2.0 AI 人生顾问(档案化问答 + 订阅 + 咨询)
AI Life OS 用户长期人生数据库(记忆 · Agent · 多模态 · 具身)
```
**第一梯队护城河(公开叙事)**:生命档案 · AI「问」· 关系系统 · AI 玩法广场
**第二梯队获客**:MBTI · 星座星盘 · 塔罗 · 测评
**第三梯队**:商城 · 广告 · 周边
---
## §5 与愈心谷对照(一句话)
学:**档案化 AI、五 Tab 战略位、订阅为主、关系对象、分享裂变、克制广告。**
弃/降权:运势主叙事、塔罗/重玄学默认、UGC 玩法广场冷启动、达人双边、硬件、多智能体品牌矩阵。
替换:数字性格 + 中医体质 + 节气陪伴 + 合规生活建议。
落地见 [feature-map.md](feature-map.md)。
+212
View File
@@ -0,0 +1,212 @@
# 愈心谷 — Product Feature Map
**权威产品能力树**(PRD / 路由 / 竖切范围以此为准)。
竞品原文树:[cece-feature-map.md](cece-feature-map.md)
领域实体:[../domain/domain-map.md](../domain/domain-map.md)
词汇:[../domain.md](../domain.md) · PRD`apps/docs/prd-mvp.md`
标记:`[MVP]` `[V1]` `[Later]` `[No]`
---
## L0 — App 信息架构
```
愈心谷
├── 首页 HomeWash:品牌 + Decode + Feed
├── 探索 Scale / Decode / 轻工具
├── 问 Ask(战略中心 Tab)
├── 陪伴 SolarTerm + Mood
├── 我的 Life Profile 资产
├── 增长运营(横切)
└── 平台生态(横切 · 后置)
```
路径:`发现 → 建档/测评 → 问/陪伴留存 → 会员·解锁 →(后)Consult`
---
## L1 — 产品能力树(合并 IA × Domain)
```
愈心谷 Feature Tree
├── 1. Identity & 生命档案
├── 2. Self Discovery(自我探索)
├── 3. Relationship(关系)
├── 4. AI Companion(问)
├── 5. Companion Rhythm(陪伴节奏)
├── 6. Human Expert(真人 · 后置)
├── 7. Content & Feed
├── 8. Growth
├── 9. Commerce
└── 10. Data & Recommendation(平台能力)
```
---
### 1. Identity & 生命档案
| 二级 | 三级 | 范围 |
|---|---|---|
| 1.1 注册登录 | 手机 / 微信 / 游客 device / 升级 User | [MVP] 游客+升级;微信 [V1] |
| 1.2 Self Profile | 生日(必填);时辰/地点(可选后置) | [MVP] 生日 |
| 1.3 Other Profile | 伴侣/家人/朋友等关系对象 | [MVP] 基础 Other |
| 1.4 档案管理 | 编辑 · 删除 · 多档案切换 · Ask 关联 | [MVP] |
| 1.5 兴趣标签 | 性格/关系/养生等(非运势标签) | [V1] |
| 1.6 行为资产 | 浏览 · Decode · Scale · Ask · Order 记录 | [MVP] 服务端最小集 |
**[No]** 出生地理风水必填、吉凶标签画像。
---
### 2. Self Discovery(获客工具层)
| 二级 | 三级 | 范围 |
|---|---|---|
| 2.1 Decode | 数字性格 + 体质倾向;简版结论 / 完整原因+方案 | **[MVP] 核心** |
| 2.2 Scale 性格 | MBTI 等热门量表 · 结果页 · 分享 | [MVP] ≥1 热门 |
| 2.3 Scale 情感/心理 | 恋爱人格、情绪压力等 | [V1] |
| 2.4 趣味 Scale | 轻传播向 | [V1] 克制 |
| 2.5 五行/八卦轻解读 | 挂在 Decode 或探索,非运势主叙事 | [V1] |
| 2.6 中医体质系统 | 体质倾向 · 生活建议 · 节气联动 | [MVP] 在 Decode 内;深化 [V1] |
**[No]** 塔罗默认入口、紫微/抽签主路径、今日运势主 Feed。
**[Later]** 易经决策系统(合规评审后)。
---
### 3. Relationship
| 二级 | 三级 | 范围 |
|---|---|---|
| 3.1 Match | 双人契合分预览 · 解读锁定 | [MVP] |
| 3.2 相处建议 | 基于性格×体质,非合婚吉凶 | [MVP] 简版;[V1] 完整 |
| 3.3 关系管理 | 重要日期、关系笔记 | [Later] |
**[No]** 八字合婚吉凶、缘分指数恐吓文案。
---
### 4. AI Companion(问 = AI Life Assistant
| 二级 | 三级 | 范围 |
|---|---|---|
| 4.1 Ask 对话 | 性格 / 关系 / 养生路径引导;非运势默认 | [MVP] 规则模板或薄 LLM |
| 4.2 上下文 | 当前 ProfileSelf/Other)挂载 | **[MVP]** |
| 4.3 视角切换 | Ask 顶栏显式切换档案 | [MVP] |
| 4.4 结构化回答 | 短答 · 要点 · 免责声明 | [MVP] |
| 4.5 长期记忆 | 跨会话情绪/事件记忆 | [V1+] |
| 4.6 报告生成 | 从 Ask/Decode 生成可 Unlock Report | [V1] |
| 4.7 双轨入口 | Ask ‖ Consult 占位切换 | [MVP] 占位;履约 [Later] |
**[No]** 多智能体并列品牌(灵犀/小智式)、算命引导语、AI 心情小镇级 3D。
人格模式(产品语义,非多 App):陪伴模式 / 解读模式 — [V1]。
---
### 5. Companion Rhythm(陪伴 Tab
| 二级 | 三级 | 范围 |
|---|---|---|
| 5.1 SolarTerm | 今日节气 · 生活方式建议 | [MVP] 可静态 |
| 5.2 Mood | 打卡 · 简史 | [MVP] 最小写 |
| 5.3 情绪分析/练习 | 安抚话术、放松练习 | [V1] |
| 5.4 成长计划 | 目标 · 打卡 · 成长报告 | [Later] |
**[No]** 运势日历作为陪伴主轴。
---
### 6. Human ExpertConsult
| 二级 | 三级 | 范围 |
|---|---|---|
| 6.1 顾问类型 | 养生顾问 / 关系顾问(合规资质) | [Later] |
| 6.2 流程 | 列表 · 预约 · 支付 · 会话 · 评价 | [Later] |
| 6.3 Marketplace | 达人入驻 · 分佣 | [Later] 非冷启动优先 |
**[MVP]** 仅「顾问预约」表单占位,不履约。
---
### 7. Content & Feed
| 二级 | 三级 | 范围 |
|---|---|---|
| 7.1 首页 Feed | 官方卡片:热门 Scale、Decode、节气 | [MVP] 运营配置/静态 |
| 7.2 文章 | 性格 / 关系 / 养生知识 | [V1] |
| 7.3 社区 UGC | 发帖赞评关注 | **[No] MVP**[Later] 审慎 |
| 7.4 AI 玩法广场 | UGC Prompt 集市 | **[No] MVP**[Later] |
---
### 8. Growth
| 二级 | 三级 | 范围 |
|---|---|---|
| 8.1 分享卡 | Decode / ScaleResult / Match 预览 | [MVP] |
| 8.2 裂变 | 分享 → 建档 → 再测 | [V1] |
| 8.3 激励 | 签到积分勋章 | [Later] |
| 8.4 SEO/内容获客 | Web 落地 | [Later] website |
**[No]** 干扰广告、虚假紧迫倒计时。
---
### 9. Commerce
| 二级 | 三级 | 范围 |
|---|---|---|
| 9.1 Subscription | 月/季/年 | [MVP] mock 支付 |
| 9.2 Membership 权益 | 完整 Decode、Ask 次数、深度节气等 | [MVP] |
| 9.3 Unlock | 单次报告 / Match 解读 | [MVP] |
| 9.4 Order / Payment | 下单 · pay-mock ·(真支付) | [MVP] mock;真支付 [V1] |
| 9.5 课程/商城 | — | [Later] / 低优 |
---
### 10. Data & Recommendation(平台)
| 二级 | 三级 | 范围 |
|---|---|---|
| 10.1 用户数据 | 行为 · Mood · Scale · Ask(最小化、可删) | [MVP] 基础 |
| 10.2 推荐 | Feed / Scale 推荐 | [V1] 规则即可 |
| 10.3 专家/商品推荐 | — | [Later] |
---
## L2 — 页面 / 路由映射(user-h5)
| L0 | 路由建议 | 主要能力 |
|---|---|---|
| 首页 | `/` | Decode 入口、Feed |
| 探索 | `/explore` | Scale 列表、工具 |
| 问 | `/ask` | Ask + Consult 占位 |
| 陪伴 | `/companion` | SolarTerm、Mood |
| 我的 | `/mine` | Profiles、Membership、Orders |
| 二级 | `/decode` `/scales/:slug` `/match` `/report/:id` | Discovery / Relationship / Commerce |
实现约束:`.ai/design/*` · playbook `new-page` / `add-api`
---
## 护城河优先级(愈心谷)
| 梯队 | 能力 | 说明 |
|---|---|---|
| ★★★★★ | 生命档案 Profile · Ask 挂档案 · Relationship Match · Decode(性格×体质) | Memory + 差异化叙事 |
| ★★★★ | Scale · SolarTerm/Mood · Membership/Unlock | 获客与留存与变现 |
| ★★ | Feed 运营 · 分享裂变 | 增长 |
| ★ / No | UGC 广场 · 达人市场 · 硬件 · 塔罗主路径 | 明确后置或不做 |
---
## 竖切顺序(与 roadmap 对齐)
1. **Phase A** — Identity + Decode + Commerce mock
2. **Phase B** — Scale + Match + Share
3. **Phase C** — Ask 骨架 + Companion
4. **Phase D** — 真支付 · 小程序 · Consult 试点
详见 `apps/docs/product-roadmap.md`
+17
View File
@@ -0,0 +1,17 @@
# Prompt: Bugfix
Load first: `.ai/constitution.md`, `.ai/coding.md`, `.ai/security.md`, `.ai/review.md`.
## Process
1. Reproduce or state the failure mode clearly.
2. Find root cause (file + function). Prefer evidence over guess.
3. Fix the smallest correct change.
4. Add a regression test when the bug is in scoring, auth, or payment.
5. Verify build/health.
6. Output Review block (at least Architecture, Security, Test, Scope).
## Forbidden
- Drive-by refactors unrelated to the bug.
- Swallowing errors to “make it pass”.
+18
View File
@@ -0,0 +1,18 @@
# Prompt: New Feature
Load first: `.ai/constitution.md`, `.ai/architecture.md`, `.ai/coding.md`, `.ai/api.md`, `.ai/review.md`, `.ai/definition-of-done.md`.
## Process
1. Restate the feature in one sentence and list files you will touch.
2. Follow feature flow: API → Service → Repository → Migration → SDK/types → UI → Test → Docs.
3. Implement the smallest vertical slice that works end-to-end.
4. Run builds/tests for touched sides.
5. Output `.ai/review.md` Review block.
6. Confirm Definition of Done.
## Forbidden
- Inventing APIs not in the task / OpenAPI.
- Editing legacy root HTML unless migration is the task.
- Shipping UI-only unlock/payment without server checks.
+16
View File
@@ -0,0 +1,16 @@
# Prompt: Refactor
Load first: `.ai/constitution.md`, `.ai/architecture.md`, `.ai/coding.md`, `.ai/testing.md`, `.ai/review.md`.
## Process
1. State goal and non-goals. No behavior change unless asked.
2. Keep layers intact. Improve names, size, and boundaries.
3. Prefer move/extract over rewrite.
4. Keep tests green; add tests if extracting scorable logic with none.
5. Output Review block focusing on Architecture, Readability, Test, Scope.
## Forbidden
- Mixing refactor with feature work in one change set.
- Breaking public API envelope or URL contracts silently.
+40
View File
@@ -0,0 +1,40 @@
# AI Self-Review — mandatory before claiming Done
After coding, check every item. Output a Review block.
## Checklist
| Area | Ask |
|---|---|
| Architecture | Layers respected? No Handler→DB? |
| Naming | Consistent domain terms? |
| Performance | Obvious N+1 / unbounded lists? |
| Security | AuthZ, validation, no secrets? |
| Readability | Files ≤400, funcs ≤50? |
| Error handling | Wrapped errors / user-safe messages? |
| Logging | Structured, no PII spam? |
| Test | Critical path covered or smoke listed? |
| Deployment | Migration / health / env noted if needed? |
| Docs | OpenAPI / PRD touch if public behavior changed? |
| Design | UI change? Tokens + catalog + platform contract followed? |
| Scope | No unrelated files modified? |
## Output format (required)
```
## Review
- Architecture: PASS | FAIL — <note>
- Naming: PASS | FAIL — <note>
- Performance: PASS | FAIL — <note>
- Security: PASS | FAIL — <note>
- Readability: PASS | FAIL — <note>
- Error handling: PASS | FAIL — <note>
- Logging: PASS | FAIL — <note>
- Test: PASS | FAIL — <note>
- Deployment: PASS | FAIL — <note>
- Docs: PASS | FAIL — <note>
- Design: PASS | FAIL | N/A — <note>
- Scope: PASS | FAIL — <note>
```
Any FAIL → fix before finishing. Do not hide FAILs.
+26
View File
@@ -0,0 +1,26 @@
# Security — Golden Rules
## AuthZ
- Authenticate before mutating user data.
- Authorize ownership: user A cannot read/write user B resources.
## Input
- Validate all external input at handler boundary.
- Parameterized SQL only. Never string-concatenate SQL.
## Secrets
- No secrets in repo, frontend bundles, or logs.
- Rotate via env / secret manager.
## Privacy
- Birthday / answers / reports are personal data.
- Soft-delete and future account deletion path required in design.
- Log request ids; avoid logging full PII payloads.
## Content compliance
- Reject generating 疗效 / 吉凶文案 in prompts and templates.
+42
View File
@@ -0,0 +1,42 @@
# Tech Stack — frozen unless ADR says otherwise
## Backend
- Language: Go 1.22+
- HTTP: gin
- DB: PostgreSQL
- Migrations: goose (or golang-migrate) under `apps/api/migrations/`
- Log: structured (zap or slog wrapper). No `fmt.Println` in business paths.
- Module path: `github.com/yuxingu/digital-psychology/apps/api`
## User H5
- Vue 3 + TypeScript (`strict: true`) + Vite
- Router: vue-router
- State: pinia
- Package: `@yuxingu/user-h5`
## Shared
- npm workspaces at repo root
- `@yuxingu/sdk` `createClient({ baseURL, adapters })`
- TS camelCase in app; SDK converts to/from API snake_case
## Mini program
- Native WeChat mini-program structure
- Same SDK via adapters (`wx.request`, storage)
- No shared Vue SFC with H5
## Deploy
- Docker Compose for local Postgres: `deploy/docker-compose.yml`
- API health: `/api/v1/healthz` (liveness). Add readiness when DB is wired.
- Never deploy with image tag `latest` in prod.
## Do not introduce without ADR
- Another backend language
- GraphQL / gRPC as primary public API (REST is primary)
- ORM that hides SQL without team agreement
- New state manager besides Pinia on H5
+22
View File
@@ -0,0 +1,22 @@
# Testing — Golden Rules
## Priority
Test money, scoring, auth, and unlock paths first.
## Go
- Pure engines (decode / scale scoring) must have unit tests.
- `go test ./...` must pass before claiming API done.
## H5
- Critical utils may use Vitest when introduced.
- Until then: PR must list manual smoke steps for touched flows.
## Definition for AI
Do not mark a feature Done if:
- Scorable logic has zero tests, or
- Build is broken (`go test` / `npm run build:h5` fail).
+64
View File
@@ -0,0 +1,64 @@
# UI — Product chrome + pointer to Design Contract
**Visual / component rules:** `.ai/design/design-system.md` (mandatory before UI work).
**Catalog:** `.ai/design/component-catalog.md`
**Platform:** `.ai/design/platform/h5.md` (default) · `mini-program.md` · `website.md` · `flutter.md`
---
## Brand (summary)
- Primary `#E54D42``--color-primary` / `--yxg-pri`
- Atmosphere: peach wash → white sheet
- Mobile-first; user column ~430px
- Unicode symbols over emoji in chrome
---
## H5 structure
```
apps/user-h5/src/
pages/
components/
layouts/
hooks/
api/
stores/
router/
assets/
```
No raw `fetch` in `pages/`. Tokens from `packages/ui`.
---
## Tabs (product IA)
Home / Explore / **Ask** / Companion / Mine.
Ask is the strategic center tab.
---
## Copy / compliance
- No medical cure claims
- No 吉凶祸福
- Report screens include disclaimer
- Brand voice: see design-system §13
---
## Interaction
- One job per section
- Home first viewport: brand, decode entry, then content sheet
- Loading / empty / error required for network views
---
## Mini program
- Own `components/`; share tokens from `packages/ui`, not Vue SFCs
- Pages → `services/*` only
- See `design/platform/mini-program.md`
+33
View File
@@ -0,0 +1,33 @@
# Workflow — Default Development Loop
```
Receive task
Read AI Contract + constitution + architecture + domain
Architecture Check (ADR + file-map + layers)
Choose playbook (add-api / new-page / new-table / …)
Coding (follow patterns + examples)
Commands (build / test / health)
Review (.ai/review.md)
DoD + checklist
Commit (Conventional Commits, one concern)
```
## Architecture Check questions
1. Does this change reverse an Accepted ADR? If yes → ASK / new ADR.
2. Correct layer? Handler / Service / Repository?
3. Domain words match `.ai/domain.md`?
4. API envelope still `{code,message,data}`?
## Stop conditions
- Unclear requirement → ASK FIRST
- Need GraphQL / new DB / new auth scheme → write or cite ADR before coding
+13
View File
@@ -0,0 +1,13 @@
# Cursor as Agent Runtime
`.cursor/` is **not** a second source of truth.
Everything under `rules/`, `templates/`, `commands/` is a **symlink** into `.ai/`.
| Cursor path | Points to |
|---|---|
| `rules/*.md` | `.ai/*.md` (constitution, architecture, coding, …) |
| `templates/feature.md` | `.ai/playbooks/add-api.md` |
| `commands/review.md` | `.ai/review.md` |
Edit only `.ai/`. Never duplicate content here.
+1
View File
@@ -0,0 +1 @@
../../.ai/commands.md
+1
View File
@@ -0,0 +1 @@
../../.ai/prompts/refactor.md
+1
View File
@@ -0,0 +1 @@
../../.ai/review.md
+1
View File
@@ -0,0 +1 @@
../../.ai/ai-contract.md
+1
View File
@@ -0,0 +1 @@
../../.ai/api.md
+1
View File
@@ -0,0 +1 @@
../../.ai/architecture.md
+1
View File
@@ -0,0 +1 @@
../../.ai/coding.md
+1
View File
@@ -0,0 +1 @@
../../.ai/constitution.md
+1
View File
@@ -0,0 +1 @@
../../.ai/database.md
+1
View File
@@ -0,0 +1 @@
../../.ai/design/design-system.md
+1
View File
@@ -0,0 +1 @@
../../.ai/domain/domain-map.md
+1
View File
@@ -0,0 +1 @@
../../.ai/domain.md
+1
View File
@@ -0,0 +1 @@
../../.ai/product/feature-map.md
+1
View File
@@ -0,0 +1 @@
../../.ai/forbidden.md
+1
View File
@@ -0,0 +1 @@
../../.ai/review.md
+1
View File
@@ -0,0 +1 @@
../../.ai/checklists/feature.md
+1
View File
@@ -0,0 +1 @@
../../.ai/playbooks/add-api.md
+20
View File
@@ -4,3 +4,23 @@ __pycache__/
*.log
.env
.DS_Store
# Node
node_modules/
dist/
*.local
# Go
apps/api/bin/
*.exe
# IDE
.idea/
.vscode/
# Data / local db
*.db
.scale_results.db
# OS
Thumbs.db
+44
View File
@@ -0,0 +1,44 @@
# AGENTS.md — AI System Entry
You are the software engineer for **愈心谷 (YuXinGu)**.
This file is for AI agents.
## Load order (every task)
1. `.ai/ai-contract.md`
2. `.ai/constitution.md`
3. `.ai/architecture.md`
4. `.ai/domain.md` (+ product/API tasks: `domain/domain-map.md`)
5. `.ai/forbidden.md`
6. `.ai/file-map.md` + `.ai/workflow.md`
7. Task rules: `.ai/coding.md` / `api.md` / `database.md` / `ui.md` / `security.md` / …
8. **Product scope / PRD slicing:** `.ai/product/feature-map.md` (竞品对照: `product/cece-feature-map.md`)
9. **Any UI work:** `.ai/design/design-system.md` + `component-catalog.md` + matching `design/platform/*.md` (H5 default)
10. Matching **ADR** in `.ai/adr/` before changing stack or API style
11. Prefer **patterns/** + **examples/** + **playbooks/** over inventing structure
12. Before Done: `.ai/review.md` + `.ai/definition-of-done.md` + `.ai/checklists/*`
13. Verify via `.ai/commands.md`
14. `prompts/` are optional helpers — not a substitute for rules above
## Hard constraints
- Never violate architecture or Accepted ADRs.
- Never invent APIs, DB tables, or domain synonyms.
- Never guess requirements — **ASK FIRST**.
- Never modify files outside the current task.
- New code only under `apps/` and `packages/` (unless legacy migration task).
- One concern per change set. Function ≤50 lines. File ≤400 lines.
- Print the Review block when a coding task finishes.
## Cursor
`.cursor/` is an Agent Runtime view of this system via symlinks. Edit `.ai/` only.
## Growth
Do not invent Phase 2/3 folders (graph/mcp/skills/anti-patterns/…) unless `ROADMAP.md` says so and the task asks. Prefer improving patterns/examples/playbooks.
## Product one-liner
Birthday → Profile (digital personality + constitution) → Companion / Ask retention → Membership & Report unlock → Consult later. Compliant lifestyle wording only.
+9
View File
@@ -0,0 +1,9 @@
# ARCHITECTURE.md
Canonical architecture rules for AI and humans live in:
**[.ai/architecture.md](.ai/architecture.md)**
**[.ai/tech-stack.md](.ai/tech-stack.md)**
**[.ai/constitution.md](.ai/constitution.md)**
Start at [AGENTS.md](AGENTS.md).
+35 -50
View File
@@ -1,64 +1,49 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
愈心谷 is an **AI-first** Monorepo. Treat `.ai/` as the executable engineering system.
## Project overview
## On every task
愈心谷 (YuXinGu) — a digital mental health platform. The codebase is a collection of standalone, mobile-first HTML pages with no build step, no framework, no package.json, and no JavaScript dependencies.
1. Read [AGENTS.md](AGENTS.md) (load order is authoritative).
2. Especially: `.ai/ai-contract.md`, `constitution.md`, `architecture.md`, `domain.md`, `forbidden.md`.
3. Prefer `patterns/` + `examples/` + `playbooks/` over free-form invention.
4. Finish with Review + DoD + matching checklist.
The product vision is detailed in `立项文档.md` (Chinese): combine digital psychology (numerology-based personality analysis) with TCM constitution theory (中医体质) to create a "test → report → subscribe → consult" funnel. Target audience is Chinese-speaking; all UI text is Chinese (zh-CN).
## Layout
## Running the app
| Path | Role |
|---|---|
| `.ai/` | AI Engineering System (source of truth for rules) |
| `apps/api` | Go API |
| `apps/user-h5` | Vue3 user H5 |
| `apps/mini-program` | Mini-program scaffold |
| `packages/*` | sdk / types / utils / ui |
| `apps/docs/` | Human PRD / business docs (not a substitute for `.ai/`) |
## Commands
```bash
python3 server.py [port] # default port 8001
export GOPROXY=https://goproxy.cn,direct # if needed
cd apps/api && go run ./cmd/server
npm install && npm run dev:h5
```
The server serves static files from the project root and exposes two JSON API endpoints:
## Legacy
- `GET /load` — returns mindmap data from `mindmap_data.json`
- `POST /save` — persists mindmap data to `mindmap_data.json` (validates JSON before writing)
Root `yuxingu.html`, `pages/`, `server.py` = prototype. Do not extend. See [LEGACY.md](LEGACY.md).
There are no tests, no linters, and no build pipeline. To verify changes, run the server and open the relevant HTML file in a browser.
## Skill routing
## File map
When the user's request matches an available skill, invoke it. When in doubt, invoke the skill.
| File | Purpose |
|---|---|
| `index.html` | Landing page linking to all sections |
| `yuxingu.html` | Main app shell — hero, service cards, activity center, bottom nav |
| `shuzi.html` | Digital psychology calculator — life-number triangle, bagua, liuren, zodiac, wuxing modules |
| `mindmap.html` | Canvas-based mind-map editor with multi-map management |
| `yangsheng.html` | AI Eastern wellness — bazi/wuxing constitution analysis, weekly/daily reports |
| `manual.html` | Static "life manual" poster with pyramid triangle charts rendered via inline SVG |
| `yuxingu_v1.html` | Earlier iteration of the main page (kept for reference, not linked from index) |
| `server.py` | Minimal HTTP server (Python stdlib, no dependencies) |
| `立项文档.md` | Product requirements doc — market analysis, business model, pricing, MVP scope |
### Unrelated files
These files are not part of the 愈心谷 app — they belong to a separate crypto trading visualization project that happens to share the repo:
- `link_regime_chart.html` — LINK token HMM regime K-line chart
- `l2_LINK_*.json` (3 files) — market data and signals for the above
## Architecture notes
- **Every HTML file is self-contained.** All CSS and JS are embedded in `<style>` / `<script>` tags. There are no shared `.js` or `.css` files.
- **Mobile-first design** with `max-width: 430px500px` containers, `user-scalable=no`, and `env(safe-area-inset-bottom)` for notched phones.
- **CSS custom properties** define the brand palette: `--pri: #E54D42` (primary red), with per-page accent colors (gold, blue, green, orange).
- **Emoji are deliberately avoided** in the main UI — icons use CSS shapes, Unicode text symbols (△, ☯, ◈), or inline SVG.
- **Google Analytics** (`G-LVVXH3TL04`) is embedded in every HTML page via a `<script>` block in `<head>`.
- **Static assets**: `logo.png`, `logo.jpg`, `cube.jpg`. The logo is referenced from multiple pages but lives at the project root.
### Page-specific details
**`mindmap.html`** — Uses `<canvas>` for rendering with hand-rolled hit-testing, drag-to-pan, and inline text editing. Dual persistence: primary store is `localStorage` (key `yuxingu_maps`), with secondary server sync via `POST /save` and `GET /load`. The sidebar lists multiple named maps; each map is a tree with colored nodes. Data format is an array of `{name, tree: {id, text, color, children}}` objects.
**`shuzi.html`** — Full numerology engine in embedded JS: digit reduction, triangle calculation, joint codes, missing-number detection. Includes a custom base64-embedded font (`TriangleDigits`) for styled number rendering. Tabbed panels for 梅花易数, 小六壬, 大六壬, 奇门遁甲, 星座, and 五行八卦 with content rendered dynamically. Also includes a 3D bagua scene rendered on canvas.
**`yangsheng.html`** — Computes bazi (八字), five elements (五行), organ-meridian mapping, and wuyun-liuqi (五运六气) from a birth date. Weekly/daily panels use the current date to generate time-appropriate health advice. Builds on the same numerological engine concepts as `shuzi.html` but oriented toward TCM wellness rather than personality analysis.
**`manual.html`** — A static reference poster. Uses inline SVG to draw pyramid triangle charts for life-number interpretation. Different aesthetic (serif fonts, paper-like colors) from the rest of the app.
**`server.py`** — Thin wrapper around `http.server.SimpleHTTPRequestHandler`. Disables caching for HTML and JSON responses. Adds `/save` + `/load` routes. No database, no auth. Single-threaded with a 30-second socket timeout. Binds to `127.0.0.1` only (no external network access).
- Product ideas/brainstorming → `/office-hours`
- Strategy/scope → `/plan-ceo-review`
- Architecture → `/plan-eng-review`
- Design → `/design-consultation` or `/plan-design-review`
- Full review pipeline → `/autoplan`
- Bugs/errors → `/investigate`
- QA → `/qa` or `/qa-only`
- Code review → `/review`
- Ship/PR → `/ship` or `/land-and-deploy`
- Save/resume context → `/context-save` / `/context-restore`
- Spec/issue → `/spec`
+31
View File
@@ -0,0 +1,31 @@
# CONTRIBUTING
## AI-first
This project is driven by the **AI Engineering System** under [`.ai/`](.ai/).
Agents must load [AGENTS.md](AGENTS.md) and `.ai/*` before coding.
Human product docs (PRD, business) stay in `apps/docs/`.
Do **not** treat `apps/docs/standards/` as the source of truth — it only points here for history.
## Local
```bash
# optional CN Go proxy
export GOPROXY=https://goproxy.cn,direct
cd apps/api && go mod tidy && go run ./cmd/server
npm install && npm run dev:h5
docker compose -f deploy/docker-compose.yml up -d # postgres
```
## Git
Trunk-Based: short `feature/*` / `fix/*` into `main`.
Commits: Conventional Commits (`feat:`, `fix:`, `docs:`, …).
## PR
- One feature point.
- Include Review checklist results when AI-assisted.
- API changes update `proto/openapi.yaml`.
+9
View File
@@ -0,0 +1,9 @@
# Legacy 原型说明
以下路径为重构前的静态 H5 原型,**默认只读**,新功能请在 `apps/user-h5``apps/api` 开发:
- `yuxingu.html``index.html`
- `pages/``css/``js/`
- `server.py`Python 静态站 + 量表 API
可对照交互与文案,迁移完成后移入 `archive/legacy-h5/`
+48
View File
@@ -0,0 +1,48 @@
# 愈心谷(YuXinGu
数字性格 × 中医体质。MonorepoGo API + Vue3 H5,预留小程序。
## AI Engineering System(规范真相源)
本仓库是 **AI-first**:不用长篇《开发手册》当主约束,而用可执行的 **`.ai/`**
```
.ai/
ai-contract.md · constitution · architecture · domain
file-map · workflow · forbidden · commands
coding / api / database / ui / deployment / testing / security
review · definition-of-done
adr/ patterns/ examples/ playbooks/ checklists/
prompts/ # 辅助,非核心
```
优先级:constitution → architecture → domain → patterns/examples/playbooks → review/DoD → prompts。
Cursor 运行时:[.cursor/](.cursor/)(软链到 `.ai/`,不复制内容)。
演进节奏:[.ai/ROADMAP.md](.ai/ROADMAP.md)(二/三阶段:anti-patterns、metrics、graph、mcp、skills…按需再加)。
入口:[AGENTS.md](AGENTS.md) · [CLAUDE.md](CLAUDE.md) · [.ai/README.md](.ai/README.md)
产品文档(给人看):[prd-mvp](apps/docs/prd-mvp.md) · [business-model](apps/docs/business-model.md)
## 快速开始
```bash
export GOPROXY=https://goproxy.cn,direct # 若需要
docker compose -f deploy/docker-compose.yml up -d # 可选
cd apps/api && go mod tidy && go run ./cmd/server
# → http://127.0.0.1:8080/api/v1/healthz
npm install && npm run dev:h5
# → http://127.0.0.1:5173
```
## 目录
| 路径 | 说明 |
|---|---|
| `.ai/` | AI 工程系统(必须遵守) |
| `apps/api` | Go 后端 |
| `apps/user-h5` | 用户 H5 |
| `apps/mini-program` | 小程序脚手架 |
| `packages/*` | sdk / types / utils / ui |
| 根目录 HTML / `server.py` | Legacy,见 [LEGACY.md](LEGACY.md) |
+3
View File
@@ -0,0 +1,3 @@
# admin-h5
运营后台(内容库、订单、会员)。**业务后置**,当前仅占位。
+6
View File
@@ -0,0 +1,6 @@
{
"name": "@yuxingu/admin-h5",
"version": "0.1.0",
"private": true,
"description": "运营后台占位,业务后置"
}
+39
View File
@@ -0,0 +1,39 @@
// Command server starts the 愈心谷 HTTP API.
package main
import (
"log"
"os"
"github.com/gin-gonic/gin"
"github.com/yuxingu/digital-psychology/apps/api/internal/config"
"github.com/yuxingu/digital-psychology/apps/api/internal/handler"
"github.com/yuxingu/digital-psychology/apps/api/internal/middleware"
"github.com/yuxingu/digital-psychology/apps/api/pkg/response"
)
func main() {
cfg := config.Load()
if cfg.AppEnv == "prod" {
gin.SetMode(gin.ReleaseMode)
}
r := gin.New()
r.Use(gin.Recovery(), gin.Logger(), middleware.RequestID())
api := r.Group("/api/v1")
handler.NewHealthHandler().Register(api)
// Placeholder route to demonstrate unified envelope.
api.GET("/ping", func(c *gin.Context) {
response.OK(c, gin.H{"pong": true})
})
addr := cfg.HTTPAddr
log.Printf("yuxingu api listening on %s env=%s", addr, cfg.AppEnv)
if err := r.Run(addr); err != nil {
log.Printf("server stopped: %v", err)
os.Exit(1)
}
}
+34
View File
@@ -0,0 +1,34 @@
module github.com/yuxingu/digital-psychology/apps/api
go 1.22
require github.com/gin-gonic/gin v1.10.0
require (
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+89
View File
@@ -0,0 +1,89 @@
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+27
View File
@@ -0,0 +1,27 @@
// Package config loads process configuration from environment variables.
package config
import "os"
// Config holds runtime settings for the API server.
type Config struct {
HTTPAddr string
DatabaseURL string
AppEnv string
}
// Load reads configuration from the environment with safe defaults for local dev.
func Load() Config {
return Config{
HTTPAddr: getenv("HTTP_ADDR", ":8080"),
DatabaseURL: getenv("DATABASE_URL", "postgres://yuxingu:yuxingu@127.0.0.1:5432/yuxingu?sslmode=disable"),
AppEnv: getenv("APP_ENV", "dev"),
}
}
func getenv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}
+25
View File
@@ -0,0 +1,25 @@
package handler
import (
"github.com/gin-gonic/gin"
"github.com/yuxingu/digital-psychology/apps/api/pkg/response"
)
// HealthHandler serves liveness probes.
type HealthHandler struct{}
// NewHealthHandler constructs HealthHandler.
func NewHealthHandler() *HealthHandler {
return &HealthHandler{}
}
// Register mounts health routes on the engine or router group.
func (h *HealthHandler) Register(r gin.IRoutes) {
r.GET("/healthz", h.Healthz)
}
// Healthz returns a simple OK payload for load balancers.
func (h *HealthHandler) Healthz(c *gin.Context) {
response.OK(c, gin.H{"status": "ok"})
}
@@ -0,0 +1,29 @@
package middleware
import (
"crypto/rand"
"encoding/hex"
"github.com/gin-gonic/gin"
)
// RequestID attaches X-Request-ID to every request/response for tracing.
func RequestID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.GetHeader("X-Request-ID")
if id == "" {
id = newID()
}
c.Set("request_id", id)
c.Header("X-Request-ID", id)
c.Next()
}
}
func newID() string {
var b [16]byte
if _, err := rand.Read(b[:]); err != nil {
return "req-unknown"
}
return hex.EncodeToString(b[:])
}
+25
View File
@@ -0,0 +1,25 @@
// Package response provides the unified API envelope {code,message,data}.
package response
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Body is the standard JSON response shape for all HTTP APIs.
type Body struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
// OK writes a success response with optional data.
func OK(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, Body{Code: 0, Message: "success", Data: data})
}
// Fail writes a business error with HTTP status and app code.
func Fail(c *gin.Context, httpStatus int, code int, message string) {
c.JSON(httpStatus, Body{Code: code, Message: message})
}
+27
View File
@@ -0,0 +1,27 @@
# 愈心谷产品与业务文档
工程规则以仓库根目录 [`.ai/`](../../.ai/) 为准;本目录放**产品 / 商业 / 竞品分析 / ADR(业务向)**。
`apps/docs/standards/*` 已废弃,请改读 `.ai/`
---
## 阅读顺序(产品重设计)
1. [analysis/cece-teardown.md](analysis/cece-teardown.md) — 测测拆解 → 愈心谷映射
2. [`.ai/product/cece-feature-map.md`](../../.ai/product/cece-feature-map.md) — 测测 Feature MapIA × 能力域)
3. [`.ai/product/feature-map.md`](../../.ai/product/feature-map.md) — 愈心谷 Feature Map + MVP
4. [prd-mvp.md](prd-mvp.md) — MVP 目标、IA、用户故事、API 切片、验收
5. [business-model.md](business-model.md) — 三层收入与飞轮
6. [product-roadmap.md](product-roadmap.md) — Phase A→D 竖切计划
域词汇:[`.ai/domain.md`](../../.ai/domain.md) · 领域图:[`.ai/domain/domain-map.md`](../../.ai/domain/domain-map.md)
---
## 其他
| 文档 | 说明 |
|---|---|
| [adr/](adr/) | 架构/选型 ADR(与 `.ai/adr/` 分工:业务向可放此处) |
| 根目录 `立项文档.md` | 早期立项材料;冲突时以本目录 + `.ai/` 为准 |
+23
View File
@@ -0,0 +1,23 @@
# ADR 0001: Monorepo + Go API + Vue H5
## 状态
已采纳(2026-08-02
## 背景
愈心谷需从静态 HTML 原型演进为可多端扩展的产品,并引入 AI 辅助开发;需统一规范与清晰边界。
## 决策
- 采用 npm workspaces Monorepo`apps/*` + `packages/*`)。
- 后端唯一实现:Gogin)于 `apps/api`
- 当前主客户端:Vue3 + TS H5`apps/user-h5`);小程序仅脚手架。
- 多端网络层:`packages/sdk` 适配器模式。
- GitTrunk-Based + Conventional Commits。
## 后果
- 新功能不得继续堆在根目录 legacy HTML。
- 共享类型与 SDK 降低后续小程序迁移成本。
- 需维护 workspace 与 Go module 两套依赖工具链。
+7
View File
@@ -0,0 +1,7 @@
# ADR location moved
Canonical Architecture Decision Records live in:
**[../../../.ai/adr/](../../../.ai/adr/)**
This folder keeps historical notes only if needed; do not add new ADRs here.
+79
View File
@@ -0,0 +1,79 @@
# 竞品拆解:测测 → 愈心谷映射
来源:[测测 App 深度体验报告(人人都是产品经理)](https://www.woshipm.com/evaluating/6391148.html)
下游:[PRD MVP](../prd-mvp.md) · [商业模式](../business-model.md) · [产品路线图](../product-roadmap.md) · [文档索引](../README.md)
原则:学结构,不抄神秘学主叙事;愈心谷差异 = **数字性格 + 中医体质 + 关系档案 + 节气陪伴**(合规:无疗效、无吉凶)。
域词汇以 [`.ai/domain.md`](../../../.ai/domain.md) 为准。
---
## 1. 测测做对了什么(可迁移)
| 测测能力 | 本质 | 愈心谷对应 |
|---|---|---|
| 趣味测评拉新(MBTI 等) | 社交传播入口 | **Scale** + 分享卡片 |
| 生日建档 /「了解 TA」 | 关系数据资产 | **Profile**Self / Other |
| 五 Tab,中间「问」突出 | 战略入口可视化 | Home / Explore / **Ask** / Companion / Mine |
| AI 挂档案,非通用闲聊 | 垂直差异化 | **Ask** 必须带 Profile 上下文 |
| AI ‖ 真人 1v1 双轨 | 低摩擦升单 | Ask 内切换 **Consult**(后置) |
| 会员订阅为主营收 | 可预测现金流 | **Subscription****Membership** / **VIP** |
| 达人咨询高客单 | ARPU 拔高 | **Consult** |
| 砍干扰广告 | 信任优先 | 不做干扰广告 |
| 分享裂变 | 低 CAC | Decode / ScaleResult 分享 |
## 2. 测测的坑(愈心谷要避开)
| 风险 | 测测表现 | 愈心谷对策 |
|---|---|---|
| 定位拧巴 | 泛心理 vs 占星吸引力冲突 | 主叙事:文化测评 + 国标体质生活建议;重玄学模块降权 |
| AI 像「算命」 | 引导问题偏运势 | Ask 按进入路径动态引导(性格/关系/养生) |
| 视角切换难发现 | 「分析 TA」藏太深 | 首页解码后强引导建 Other ProfileAsk 顶部显式切换 Self/Other |
| 跨会话记忆弱 | 电子闺蜜体验断裂 | MVP 先做 Profile 结构化记忆;长对话记忆 V1.2+ |
| 多智能体认知负担 | 入口并列 | **只做一个 Ask**;不并行灵犀/小智式品牌矩阵 |
## 3. 信息架构对照
```
测测: 首页 | 消息 | 问 | 在线 | 我的
愈心谷: 首页 | 探索 | 问 | 陪伴 | 我的
```
- **探索** ≈ 测测首页宫格 + AI 玩法广场的「内容供给」(MVP 不做 UGC 广场,只做官方 Scale / Decode 入口)
- **陪伴** ≈ 每日心情 + 节气(测测心情打卡的留存位,换成 SolarTerm + Mood
- **消息 / 在线** 后置;Consult 先做预约表单,不做达人双边平台
## 4. 核心用户路径(对标测测三条场景)
### P1 自我探索(拉新)
Visitor → 首页 Decode 或 Scale → 简版结论 → 分享 → 注册为 User
### P2 关系决策(差异化)
User 建 Other Profile → Match 预览分数 → Unlock 解读 →(可选)Ask 切换 TA
### P3 情绪 / 养生留存(夜间场景)
Mood 打卡 / SolarTerm → Ask(档案上下文)→ 额度用尽 → Subscription
## 5. 能力分层(对标测测「情感陪伴层」)
```
入口层(免费) Decode 简版 / Scale 部分 / Share
留存层(VIP Ask 额度 / SolarTerm 个性化 / Mood / 多 Profile
转化层(高客单) Report Unlock / Match / Consult
```
## 6. 不做清单(相对测测)
- 不自研大模型备案叙事(可接外部 LLM)
- 不做硬件(巴布类)
- 不做达人双边平台冷启动
- 不做 AI 心情小镇 / 3D 沙盘(成本高,非差异化必需)
- Legacy 根目录 HTML 不承接新需求(见 `.ai/architecture.md`
## 7. 结论(一句话)
测测验证了「测评入口 → 档案化 AI → 订阅 + 咨询」飞轮;愈心谷用 **体质与节气** 替换「运势主叙事」,用 **家庭/关系 Profile** 做裂变,用 **合规生活建议** 守住审核与信任。
+90
View File
@@ -0,0 +1,90 @@
# 愈心谷商业模式
关联:[PRD MVP](prd-mvp.md) · [测测拆解](analysis/cece-teardown.md) · [产品路线图](product-roadmap.md)
---
## 1. 一句话
用「数字性格 + 中医体质」做**可复算、可对照**的自我认知入口,以**订阅为主、报告/契合为辅、咨询为远期高客单**,承接测测式漏斗,但避开算命与医疗承诺。
---
## 2. 价值主张
| 对用户 | 对产品 |
|---|---|
| 知道「我是谁 / 我缺什么 / 怎么相处」 | 低摩擦获客(生日 / 量表) |
| 比泛星座更「有结构」、比纯心理量表更「东方语境」 | 差异化:体质 × 性格 × 关系档案 |
| 节气与日更内容形成回访理由 | 订阅续费钩子 |
---
## 3. 收入三层(对齐测测,本地化)
```
L1 免费获客 Decode 简版 / Scale / 分享卡
L2 订阅留存 MembershipAsk 次数、完整报告、SolarTerm 深度、Mood 复盘
L3 高 ARPU Unlock 单次报告/Match ·(远期)Consult
```
| 层级 | 产品 | 定价方向(可调) | 备注 |
|---|---|---|---|
| L1 | 简版 Decode、热门 Scale | 0 | 结论可见 |
| L2 | 月/季/年 VIP | 参考测测档位,偏下探试价 | 主收入 |
| L2.5 | Unlock 完整报告 / Match 解读 | 单次低客单 | 不愿订也可转化 |
| L3 | Consult | 远期 | 需履约与合规,非 MVP |
**不做:** 侵入式广告、诱导抽奖、伪医疗售卖。
---
## 4. 飞轮
```mermaid
flowchart LR
Share[分享卡/社交] --> Free[免费测评]
Free --> Profile[档案沉淀]
Profile --> Paywall[原因与方案付费墙]
Paywall --> VIP[订阅]
VIP --> Ask[问 / 陪伴回访]
Ask --> Share
Profile --> Match[关系档案]
Match --> Unlock[单次解锁]
Unlock --> VIP
```
关键:Profile 越多 → Match/Ask 越有用 → 续费与解锁越高。
---
## 5. 单位经济(假设,待校验)
| 指标 | MVP 观测 |
|---|---|
| 免费完成率 | Decode 简版 / Scale 完成率 |
| 付费转化 | 简版→Unlock 或 VIP |
| ARPU | 订阅为主,Unlock 为辅 |
| 留存 | D1/D7;节气打开率 |
| 合规成本 | 客服投诉 / 违规文案拦截率 |
付费与权益**只信服务端**(见 `.ai/security.md`)。
---
## 6. B2B / 扩展(非 MVP
企业 EAP、线下门店引流、内容授权——在 C 端漏斗跑通后再开。平台扩展路径:H5 → 小程序(同一 `packages/sdk`)。
---
## 7. 与测测的差异化(商业)
| 测测 | 愈心谷 |
|---|---|
| 星盘+心理+社交玩法宽 | 数字性格+体质窄而深 |
| 强娱乐/玄学氛围 | 可复算、生活建议、免责声明 |
| 咨询达人网络 | 先模板 Ask,后 Consult |
| UGC 广场 | 暂不做,避免内容治理成本 |

Some files were not shown because too many files have changed in this diff Show More