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 2fb1dfee14
193 changed files with 8854 additions and 1851 deletions
+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