Add plantings backend: plop CRUD, derived counts, removed_at (#14)
- domain: Planting gains a computed (non-persisted) DerivedCount field. - store/plantings.go: Get/Create/Update (version-guarded)/Delete alongside the existing /full read helper. - service/plantings.go: place/move/resize/soft-remove a plop; editor role on the object's garden; object must be plantable; plant_id must be visible to the actor (built-in or own) else ErrInvalidInput; center must sit within the object's unrotated local bounds (radius may overhang); planted_at defaults to today. derivedCount = max(1, round(π·r²/spacing²)) — one unit-tested helper, reused by /full (via a spacing map, no N+1) and single responses. - api: POST /objects/:id/plantings, PATCH/DELETE /plantings/:id; nullable count/label/plantedAt/removedAt use RawMessage so null (clear) is distinct from absent (unchanged). removedAt is the soft-remove / "clear bed" seam. - /full now enriches each active plop with its derivedCount. Service tests: formula edge cases (tiny radius → 1), defaults + derived, count override, move/resize + clear override, non-plantable rejection, foreign/unknown plant rejection, bounds, soft-remove leaves /full, version conflict, cross-user masking, delete. Plus an API-level create/patch/full/delete flow. GOWORK=off go build/vet/test ./internal/... green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi
This commit is contained in:
@@ -186,4 +186,10 @@ type Planting struct {
|
||||
Version int64 `json:"version"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
|
||||
// DerivedCount is the plant count implied by the plop's area and the plant's
|
||||
// mature spacing: max(1, round(π·r² / spacing²)). It is computed by the
|
||||
// service, never persisted (the store scan leaves it 0). The effective count
|
||||
// a client shows is Count when non-nil, else DerivedCount.
|
||||
DerivedCount int `json:"derivedCount"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user