docs(19.1-01): summarize userfriends tracer, groups, adapter and GDPR
Record the proceed-and-push lock, sibling repo commits, tea remote, and Task 3 deviations so later 19.1 plans can consume the new plugin. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
225
.planning/phases/19.1-chat-satellites/19.1-01-SUMMARY.md
Normal file
225
.planning/phases/19.1-chat-satellites/19.1-01-SUMMARY.md
Normal file
@@ -0,0 +1,225 @@
|
||||
---
|
||||
phase: 19.1-chat-satellites
|
||||
plan: 01
|
||||
subsystem: userfriends
|
||||
tags: [userfriends, friends, groups, festival, postgres, gorm, testcontainers, jwt]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 19
|
||||
provides: analog sibling-plugin layout (boot steps, IF NOT EXISTS baseline, build-time chat Registry, test-only proof host)
|
||||
- phase: 11
|
||||
provides: festival Bus Listen/Fire, lagoon.Transaction, surf buckets
|
||||
provides:
|
||||
- "new repository sm-userfriends-plugin (module git.golem15.com/golem15/sm-userfriends-plugin, package userfriends, plugin golem15.userfriends), pushed to git.golem15.com at 2480ff0"
|
||||
- "idempotent baseline 202610180001_create_golem15_userfriends_baseline (six v1.1.0 tables, FriendContext singleton id=1, demo-seed v1.0.1 as comment)"
|
||||
- "FriendshipService + GroupService; festival userfriends.GroupCreated/GroupDeleted/MemberJoined/MemberLeft; optional friendcontext chat adapter; user.Deleting GDPR heir"
|
||||
- "generic JSON API under /_userfriends/api/v1 with userfriends-api 120/min and community-join 10/min"
|
||||
affects: [19.1-02, 19.1-06, sm-forum-plugin, sm-chat-plugin]
|
||||
|
||||
actuals:
|
||||
tokens: 40250
|
||||
tasks: 3
|
||||
commits: 1
|
||||
plan_head_before: 36634313afd252c8f7a5becdca420c56603d1ac6
|
||||
plan_head_after: pending-summary-commit
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "Soft chat adapter: Lookup[*chatcontracts.Registry] at Boot and skip when absent; Requires() stays golem15.user only"
|
||||
- "GDPR user.Deleting heir: ORDER BY role ASC, created_at ASC (admin before member); update owner_id so ON DELETE CASCADE does not drop the group"
|
||||
- "Generic friends API: actor from JWT; IDOR/unauthorized collapse to 404; community-join Max 10 on POST /friends/request and POST /groups/{id}/join"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- ../sm-userfriends-plugin/plugin.go
|
||||
- ../sm-userfriends-plugin/boot.go
|
||||
- ../sm-userfriends-plugin/routes.go
|
||||
- ../sm-userfriends-plugin/events/events.go
|
||||
- ../sm-userfriends-plugin/classes/friendship_service.go
|
||||
- ../sm-userfriends-plugin/classes/group_service.go
|
||||
- ../sm-userfriends-plugin/classes/group_policy.go
|
||||
- ../sm-userfriends-plugin/classes/group_visibility_gate.go
|
||||
- ../sm-userfriends-plugin/classes/friends_context_adapter.go
|
||||
- ../sm-userfriends-plugin/api/friends.go
|
||||
- ../sm-userfriends-plugin/api/groups.go
|
||||
- ../sm-userfriends-plugin/updates/202610180001_create_golem15_userfriends_baseline.go
|
||||
- ../sm-userfriends-plugin/http_tracer_test.go
|
||||
- ../sm-userfriends-plugin/README.md
|
||||
modified:
|
||||
- .planning/ROADMAP.md
|
||||
|
||||
key-decisions:
|
||||
- "Task 1 reply verbatim: proceed-and-push"
|
||||
- "Locked D-01 names (module git.golem15.com/golem15/sm-userfriends-plugin, package userfriends, PluginID golem15.userfriends, Requires golem15.user only), D-02 baseline id 202610180001_create_golem15_userfriends_baseline, D-05 prefix /_userfriends/api/v1"
|
||||
- "tea repos create --owner golem15 --name sm-userfriends-plugin succeeded; main pushed at 2480ff0 (never force). summercms.go was not pushed."
|
||||
|
||||
patterns-established:
|
||||
- "userfriends proof host: golem15.user + golem15.userfriends + a test-only teams fixture; TestFixtureAbsentFromProduction keeps the fixture id and four retired tokens out of production sources"
|
||||
|
||||
requirements-completed: [SC-19.1-1, SC-19.1-3, D-01, D-02, D-03, D-04, D-05, D-07, D-08]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "Human lock of D-01 plugin names, D-02 baseline id and D-05 prefix before the sibling repo existed"
|
||||
requirement: D-01
|
||||
verification: []
|
||||
human_judgment: true
|
||||
rationale: "Task 1 was checkpoint:decision gate=blocking-human; the user replied proceed-and-push and that lock cannot be asserted by a unit test"
|
||||
- id: D2
|
||||
description: "sm-userfriends-plugin with v1.1.0 IF NOT EXISTS baseline, FriendshipService, and JWT request/accept/list tracer under /_userfriends/api/v1"
|
||||
requirement: D-05
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "go -C ../sm-userfriends-plugin test -count=1 -short ./..."
|
||||
status: pass
|
||||
- kind: integration
|
||||
ref: "../sm-userfriends-plugin/http_tracer_test.go#TestHTTPTracer"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "ROADMAP Phase 19.1 Repos names summercms.go; SC2 names webpush-go / LiveKit / bluemonday notes; SC3 marked already met"
|
||||
requirement: SC-19.1-3
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "grep webpush-go .planning/ROADMAP.md (Task 2 acceptance)"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D4
|
||||
description: "GroupService + festival events + optional friendcontext adapter + user.Deleting GDPR heir"
|
||||
requirement: D-08
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "go -C ../sm-userfriends-plugin vet ./... && go -C ../sm-userfriends-plugin test -count=1 -short ./..."
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D5
|
||||
description: "Gitea remote golem15/sm-userfriends-plugin created and main pushed (never force)"
|
||||
requirement: SC-19.1-1
|
||||
verification:
|
||||
- kind: other
|
||||
ref: "tea repos create --owner golem15 --name sm-userfriends-plugin; git push -u origin main"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
|
||||
duration: 12min
|
||||
completed: 2026-10-18
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 19.1 Plan 01: Userfriends repo, baseline, friends tracer Summary
|
||||
|
||||
**Sibling `sm-userfriends-plugin` with the v1.1.0 IF NOT EXISTS baseline, a JWT friends HTTP tracer, group festival events, an optional chat adapter, and a GDPR heir on `user.Deleting`.**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 12 min
|
||||
- **Started:** 2026-10-18T11:09:20Z
|
||||
- **Completed:** 2026-10-18T11:21:00Z
|
||||
- **Tasks:** 3
|
||||
- **Files modified:** 37 (36 in the sibling plugin, plus `.planning/ROADMAP.md`)
|
||||
|
||||
## Task 1 human reply (verbatim)
|
||||
|
||||
proceed-and-push
|
||||
|
||||
Meaning recorded at resume: lock D-01 plugin names, D-02 baseline id `202610180001_create_golem15_userfriends_baseline`, D-05 prefix `/_userfriends/api/v1`; implement; after Task 3 is green, tea-create the remote and push main (never force).
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- New independent git repo `../sm-userfriends-plugin` (not a submodule): module `git.golem15.com/golem15/sm-userfriends-plugin`, package `userfriends`, PluginID `golem15.userfriends`, `Requires()` = `golem15.user` only.
|
||||
- Idempotent baseline `202610180001_create_golem15_userfriends_baseline` for the six PHP v1.1.0 tables; FriendContext singleton id=1; demo-seed v1.0.1 is a comment with no demo INSERTs.
|
||||
- `FriendshipService` request/accept/list plus remaining CommunityFriendsController paths; generic API prefix `/_userfriends/api/v1`; buckets `userfriends-api` Max 120 and `community-join` Max 10 Decay `time.Minute`.
|
||||
- `TestHTTPTracer` (Docker): JWT user A requests B, B accepts, A lists friends 200.
|
||||
- `GroupService` + `GroupPolicy` + `GroupVisibilityGate`; festival `userfriends.GroupCreated` / `GroupDeleted` / `MemberJoined` / `MemberLeft` fire inside the write transaction.
|
||||
- Soft chat adapter: Boot Lookup of `*chatcontracts.Registry`; skip when absent; Add alias `friendcontext` with LegacyPHPClass `Golem15\UserFriends\Models\FriendContext` (and `friendgroup`).
|
||||
- GDPR: Listen `user.Deleting`; heir oldest admin else oldest member (`ORDER BY role ASC, created_at ASC`, not MySQL `FIELD()`); else hard-delete empty group; then member and ban rows. `owner_id` is updated to the heir so Postgres `ON DELETE CASCADE` does not drop a transferred group.
|
||||
- ROADMAP Phase 19.1 Repos adds `summercms.go`; criterion 2 names webpush-go / LiveKit / bluemonday notes and drops AI-plugin wiring; criterion 3 marked already met (frozen PHP userfriends `182b514`).
|
||||
- Remote created: `https://git.golem15.com/golem15/sm-userfriends-plugin`. `git push -u origin main` succeeded (never force). summercms.go was not pushed.
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each remaining task was committed atomically. Task 1 wrote no files.
|
||||
|
||||
1. **Task 1: Confirm D-01 names, D-02 baseline id and D-05 prefix before the new repo exists** - none (decision only; human: proceed-and-push)
|
||||
2. **Task 2: Tracer (plugin repo + ROADMAP)** - `dac506a` (feat, sibling) and `f984e5e` (docs, summercms.go)
|
||||
3. **Task 3: Groups, events, chat adapter, GDPR, remaining routes** - `2480ff0` (feat, sibling)
|
||||
|
||||
**Plan metadata:** pending-summary-commit (docs: complete plan)
|
||||
|
||||
**Sibling HEAD:** `2480ff0` on `origin/main`.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `../sm-userfriends-plugin/` - full plugin tree (go.mod Go 1.27.0, analog pins, replace summercms => ../summercms.go; go.work also replaces sm-user-plugin and sm-chat-plugin)
|
||||
- `.planning/ROADMAP.md` - Phase 19.1 Repos, SC2, SC3 wording
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- Task 1 reply verbatim: proceed-and-push.
|
||||
- Locked D-01 / D-02 / D-05 as named in the continuation.
|
||||
- After Task 3 verify was green, `tea repos create --owner golem15 --name sm-userfriends-plugin` then `git push -u origin main` (never force).
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 2 - Correctness] Typed chat Registry Lookup requires a module import**
|
||||
- **Found during:** Task 3
|
||||
- **Issue:** PATTERNS analog is `app.Lookup[*chatcontracts.Registry]()`. Go cannot name that type without importing `sm-chat-plugin/contracts`, so `go.mod` gained `git.golem15.com/golem15/sm-chat-plugin`. The plan text said go.mod stay limited to the user plugin.
|
||||
- **Fix:** Import contracts only (chat plugin `init` is not pulled). `Requires()` still lists only `golem15.user`. Lookup skip when chat is not Activated. `go.work` replace `../sm-chat-plugin`.
|
||||
- **Files modified:** `../sm-userfriends-plugin/go.mod`, `go.work`, `boot.go`, `classes/friends_context_adapter.go`
|
||||
- **Verification:** `grep -c golem15.chat` on `Requires()` is 0; `go test -short ./...` pass
|
||||
- **Committed in:** `2480ff0`
|
||||
|
||||
**2. [Rule 2 - Correctness] GDPR heir also updates `owner_id`**
|
||||
- **Found during:** Task 3
|
||||
- **Issue:** PHP only promoted the heir's role. Postgres `golem15_userfriends_groups.owner_id` is `ON DELETE CASCADE`, so leaving `owner_id` on the deleting user would drop the group.
|
||||
- **Fix:** After promoting the heir, set `group.owner_id = heir.user_id` before the user row goes.
|
||||
- **Files modified:** `../sm-userfriends-plugin/classes/group_service.go` (`OnUserDeleting`)
|
||||
- **Verification:** code review against the baseline FK; unit tests of the cascade land in plan 06
|
||||
- **Committed in:** `2480ff0`
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 2 auto-fixed (Rule 2 correctness)
|
||||
**Impact on plan:** Required for a compiling soft adapter and for GDPR not to delete transferred groups. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
None beyond the deviations above. Task 1 was not re-asked. The sibling directory did not exist as a foreign module at Task 2 start.
|
||||
|
||||
## TDD Gate Compliance
|
||||
|
||||
N/A — TDD is not applicable for this plan (explicit in the execute dispatch). Tracer verify is automated-only (`HUMAN_VERIFY_MODE=end-of-phase`). After Task 2 automated verify passed: Tracer verified end-to-end — expanding.
|
||||
|
||||
## Auth gates
|
||||
|
||||
Task 1 `checkpoint:decision` `blocking-human` — user replied `proceed-and-push`. No further auth gates.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required. The Gitea repo was created in-session.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
Ready for plan 19.1-02 (forum) subject to that plan's D-17 block. `sm-userfriends-plugin` is on `origin/main` at `2480ff0`. Plan 06 still owns GroupPolicy matrix tests and goldens.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- FOUND: `../sm-userfriends-plugin/plugin.go`
|
||||
- FOUND: `../sm-userfriends-plugin/updates/202610180001_create_golem15_userfriends_baseline.go`
|
||||
- FOUND: `../sm-userfriends-plugin/events/events.go`
|
||||
- FOUND: `../sm-userfriends-plugin/http_tracer_test.go`
|
||||
- FOUND: `.planning/ROADMAP.md` (webpush-go)
|
||||
- FOUND: sibling commits `dac506a`, `2480ff0`; summercms.go `f984e5e`
|
||||
- FOUND: remote `https://git.golem15.com/golem15/sm-userfriends-plugin` pushed `main` at `2480ff0`
|
||||
|
||||
---
|
||||
*Phase: 19.1-chat-satellites*
|
||||
*Completed: 2026-10-18*
|
||||
Reference in New Issue
Block a user