docs(14.1-01): complete OAuth identities and /me routes plan
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -798,12 +798,12 @@ Plans:
|
|||||||
3. `GET /api/v1/fonoteka/me` matches the PHP response for fonoteka-mcp token callers.
|
3. `GET /api/v1/fonoteka/me` matches the PHP response for fonoteka-mcp token callers.
|
||||||
4. All three manifest entries flip from `pending` to ported with recorded PHP cases, leaving zero pending routes.
|
4. All three manifest entries flip from `pending` to ported with recorded PHP cases, leaving zero pending routes.
|
||||||
|
|
||||||
**Plans:** 2 plans
|
**Plans:** 1/2 plans executed
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
|
|
||||||
**Wave 1**
|
**Wave 1**
|
||||||
- [ ] 14.1-01-PLAN.md — Model, migration, exported Index/Destroy, JWT mount, `/me` null, D-10 recording and manifest flip
|
- [x] 14.1-01-PLAN.md — Model, migration, exported Index/Destroy, JWT mount, `/me` null, D-10 recording and manifest flip
|
||||||
|
|
||||||
**Wave 2** *(blocked on Wave 1 completion)*
|
**Wave 2** *(blocked on Wave 1 completion)*
|
||||||
- [ ] 14.1-02-PLAN.md — Unit tests last: OAuthIdentityApiTest port, migration, MeToken null, secret-leak, corpus 175/175/0
|
- [ ] 14.1-02-PLAN.md — Unit tests last: OAuthIdentityApiTest port, migration, MeToken null, secret-leak, corpus 175/175/0
|
||||||
@@ -848,7 +848,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 12. Płytarium API — Collections and Albums | 5/5 | Complete | 2026-10-02 |
|
| 12. Płytarium API — Collections and Albums | 5/5 | Complete | 2026-10-02 |
|
||||||
| 13. Płytarium API — wishlist, notifications, CSV, credentials, public routes | 6/6 | In Progress| |
|
| 13. Płytarium API — wishlist, notifications, CSV, credentials, public routes | 6/6 | In Progress| |
|
||||||
| 14. Domain jobs and external integrations | 6/6 | In Progress| |
|
| 14. Domain jobs and external integrations | 6/6 | In Progress| |
|
||||||
| 14.1. OAuth identities and fonoteka me routes (INSERTED) | 0/2 | Planned | - |
|
| 14.1. OAuth identities and fonoteka me routes (INSERTED) | 1/2 | In Progress| |
|
||||||
| 15. Cutover | 0/TBD | Not started | - |
|
| 15. Cutover | 0/TBD | Not started | - |
|
||||||
|
|
||||||
## Backlog
|
## Backlog
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ milestone: v1.0
|
|||||||
current_phase: "14.1"
|
current_phase: "14.1"
|
||||||
current_phase_name: OAuth identities and fonoteka me routes
|
current_phase_name: OAuth identities and fonoteka me routes
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 12.1-05-PLAN.md
|
stopped_at: Completed 14.1-01-PLAN.md
|
||||||
last_updated: "2026-10-05T17:48:29.325Z"
|
last_updated: "2026-10-05T19:24:46.112Z"
|
||||||
last_activity: 2026-10-05
|
last_activity: 2026-10-05
|
||||||
last_activity_desc: Completed quick task 261005-qvk (Winter icon-* mapping)
|
last_activity_desc: Completed 14.1-01-PLAN.md
|
||||||
state_head: 5c65a94db0807aed66264e706ca5cbc9344d498b
|
state_head: c3bbbcbb9f7e247c353e262d0fec8126fac78e04
|
||||||
progress:
|
progress:
|
||||||
total_phases: 22
|
total_phases: 22
|
||||||
completed_phases: 11
|
completed_phases: 11
|
||||||
total_plans: 125
|
total_plans: 125
|
||||||
completed_plans: 122
|
completed_plans: 124
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -28,12 +28,12 @@ See: .planning/PROJECT.md (updated 2026-09-16)
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 14.1 (OAuth identities and fonoteka me routes) — READY TO EXECUTE
|
Phase: 14.1 (OAuth identities and fonoteka me routes) — EXECUTING
|
||||||
Plan: 0 of 2
|
Plan: 1 of 2 complete
|
||||||
Status: Planning complete; ready to execute
|
Status: Executing Phase 14.1; next is 14.1-02 unit tests
|
||||||
Last activity: 2026-10-05 - Completed quick task 261005-qvk: Map Winter icon-* navigation names onto lucide so BM Studies and Quizzes icons render
|
Last activity: 2026-10-05 — Completed 14.1-01-PLAN.md
|
||||||
|
|
||||||
Progress: [░░░░░░░░░░] 0%
|
Progress: [█████░░░░░] 50%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
@@ -177,6 +177,7 @@ Progress: [░░░░░░░░░░] 0%
|
|||||||
| Phase 12.1 P03 | 46min | 4 tasks | 40 files |
|
| Phase 12.1 P03 | 46min | 4 tasks | 40 files |
|
||||||
| Phase 12.1 P04 | 32min | 4 tasks | 35 files |
|
| Phase 12.1 P04 | 32min | 4 tasks | 35 files |
|
||||||
| Phase 12.1 P05 | 103min | 3 tasks | 56 files |
|
| Phase 12.1 P05 | 103min | 3 tasks | 56 files |
|
||||||
|
| Phase 14.1 P01 | 90 | 4 tasks | 20 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -199,6 +200,7 @@ Progress: [░░░░░░░░░░] 0%
|
|||||||
Decisions are logged in PROJECT.md Key Decisions table.
|
Decisions are logged in PROJECT.md Key Decisions table.
|
||||||
Recent decisions affecting current work:
|
Recent decisions affecting current work:
|
||||||
|
|
||||||
|
- [Phase 14.1]: 14.1-01 Task 1 `ship-shared-full` — create `golem15_user_oauth_identities` in the shared sm-user-plugin with the full PHP column set (locked D-01 and D-07).
|
||||||
- Roadmap: gormigrate (not goose) is the migration tool, per STACK.md's more recent reasoning — ARCHITECTURE.md/PITFALLS.md text still says goose in places; treat gormigrate as authoritative when phases 3 and 5 are planned.
|
- Roadmap: gormigrate (not goose) is the migration tool, per STACK.md's more recent reasoning — ARCHITECTURE.md/PITFALLS.md text still says goose in places; treat gormigrate as authoritative when phases 3 and 5 are planned.
|
||||||
- Roadmap: two repos from day one — `summercms.go` (framework, no app knowledge) and `fonoteka.go` (sibling app repo, go.work workspace of plugins). Every phase states which repo(s) it writes to.
|
- Roadmap: two repos from day one — `summercms.go` (framework, no app knowledge) and `fonoteka.go` (sibling app repo, go.work workspace of plugins). Every phase states which repo(s) it writes to.
|
||||||
- Roadmap: the parity harness (Phase 2) and the first vertical slice (Phase 3) are sequenced immediately after kernel foundation, ahead of any further kernel broadening, to avoid the documented Scala-era bottom-up-kernel failure mode.
|
- Roadmap: the parity harness (Phase 2) and the first vertical slice (Phase 3) are sequenced immediately after kernel foundation, ahead of any further kernel broadening, to avoid the documented Scala-era bottom-up-kernel failure mode.
|
||||||
@@ -610,6 +612,6 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-10-05T12:09:49.753Z
|
Last session: 2026-10-05T19:24:45.572Z
|
||||||
Stopped at: Completed 12.1-04-PLAN.md
|
Stopped at: Completed 14.1-01-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
---
|
||||||
|
phase: 14.1-oauth-identities-and-fonoteka-me-routes
|
||||||
|
plan: 01
|
||||||
|
subsystem: api
|
||||||
|
tags: [oauth-identities, sm-user-plugin, me-token, parity, gormigrate, lagoon.Encrypted, wire.Time, throttle]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 07-user-plugin-and-authentication
|
||||||
|
provides: "sm-user-plugin sessionApp/insertUser, jwt.auth, lang YAML, controllers.writeJSON"
|
||||||
|
- phase: 08-oauth2-1-authorization-server
|
||||||
|
provides: "JWT group in fonoteka routes.go, MeToken personal-token bootstrap, TokenSurfaceIsolation coverage"
|
||||||
|
- phase: 14-domain-jobs-and-external-integrations
|
||||||
|
provides: "parity corpus at 175 PHP routes with 3 pending D-09 identity/me entries, fonoteka seed extras, php_parity.sh recording"
|
||||||
|
provides:
|
||||||
|
- "OAuthIdentity model and gormigrate 202610050001_create_oauth_identities in sm-user-plugin (table golem15_user_oauth_identities, full PHP column set)"
|
||||||
|
- "Exported OAuthIdentitiesIndex, OAuthIdentitiesDestroy, OAuthIdentitiesOptions; host JWT mounts GET/DELETE /oauth-identities with Winter HTML 404 and throttle:10,1 on DELETE"
|
||||||
|
- "D-09 MeToken collection_ids JSON null when CollectionIDs is invalid or empty; scopes still wire.Slice"
|
||||||
|
- "Parity extras oauth-identities-linked and me-unrestricted; three manifest routes ported; TestParityCorpus recorded 175/175 passing 175 failing 0 unrecorded 0 pending 0"
|
||||||
|
affects: [14.1-02 unit tests, 15-cutover (zero pending routes)]
|
||||||
|
|
||||||
|
actuals:
|
||||||
|
tokens: 5100
|
||||||
|
tasks: 4
|
||||||
|
commits: 5
|
||||||
|
plan_head_before: c3bbbcbb9f7e247c353e262d0fec8126fac78e04
|
||||||
|
plugin_repo_head_after: ac8aa16217556f70f1e1b2c0a3495c7eea6b5747
|
||||||
|
app_repo_head_after: 1584d7390d80b8f1d3e8de53c2f0144deb9ebd64
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Host-mounted constructors: sm-user-plugin exports Index/Destroy; the host chooses the path, throttle and WriteNotFound (Winter HTML 404), never a /_user route"
|
||||||
|
- "Parity extras keyed as \"<route id>#<case id>\" on both PHP tinker reset and Go seedFonotekaCase"
|
||||||
|
- "assertPortedMismatch wraps a ported fixture with mutateStatus and requires tide.MismatchError"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/models/oauth_identity.go
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/updates/202610050001_create_oauth_identities.go
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/controllers/oauth_identities.go
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/oauth_identities_test.go
|
||||||
|
- ../fonoteka.go/parity/fixtures/routes/GET___fonoteka_api_v1_oauth-identities_jwt__linked.yaml
|
||||||
|
- ../fonoteka.go/parity/fixtures/routes/GET__api_v1_fonoteka_me_personal_token__unrestricted.yaml
|
||||||
|
modified:
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/lang/en/lang.yaml
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/lang/pl/lang.yaml
|
||||||
|
- ../fonoteka.go/plugins/golem15/user/README.md
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/routes.go
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/phase08_coverage_test.go
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/api/me_token_controller.go
|
||||||
|
- ../fonoteka.go/parity/manifest.yaml
|
||||||
|
- ../fonoteka.go/parity/parity_test.go
|
||||||
|
- ../fonoteka.go/parity/parity_contract_test.go
|
||||||
|
- ../fonoteka.go/parity/fonoteka_seed_test.go
|
||||||
|
- ../fonoteka.go/parity/fonoteka_reset.php
|
||||||
|
- ../fonoteka.go/parity/genres_seed_test.go
|
||||||
|
- ../fonoteka.go/parity/fixtures/routes/GET__api_v1_fonoteka_me_personal_token.yaml
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Task 1 answered ship-shared-full before dispatch: table golem15_user_oauth_identities lives in sm-user-plugin with the full PHP column set (locked D-01 and D-07)"
|
||||||
|
- "routes.go in sm-user-plugin stays byte-identical; identity handlers are host-mounted on the fonoteka JWT group"
|
||||||
|
- "Last-method 409 counts identities only (D-06); HasSelfSetPassword is unused"
|
||||||
|
- "Restricted /me was re-recorded from the fonoteka reset so {{id:collection}} resolves; the Phase 2 {{id:token}} placeholder would not"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "OAuth identity list is an explicit {provider, linked_at} map; Encrypted tokens and profile_data are Hidden and json:\"-\""
|
||||||
|
- "DELETE {provider} is unconstrained on the mux so unknown providers reach WriteWinterHTTPError"
|
||||||
|
- "MeToken: scopes use wire.Slice; collection_ids is a bare any that stays JSON null when empty"
|
||||||
|
|
||||||
|
requirements-completed: [HTTP-04, HTTP-06]
|
||||||
|
requirements-blocked-until-02: [API-09, HTTP-01, HTTP-03, DATA-02, DATA-07, I18N-01]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: "golem15_user_oauth_identities exists in sm-user-plugin via gormigrate with Encrypted tokens, Hidden secrets, and empty Fillable"
|
||||||
|
requirement: DATA-02
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "plugins/golem15/user#TestOAuthIdentitiesIndexEmptyList"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: "JWT GET /_fonoteka/api/v1/oauth-identities returns {\"data\":[]} and, with extra oauth-identities-linked, facebook then google linked_at +00:00 without secrets"
|
||||||
|
requirement: HTTP-06
|
||||||
|
verification:
|
||||||
|
- kind: e2e
|
||||||
|
ref: "parity#TestParityCorpus coverage line recorded 175/175 passing 175"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "plugins/golem15/user#TestOAuthIdentitiesIndexEmptyList"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: "JWT DELETE /oauth-identities/{provider} is throttle:10,1, unconstrained, 204 keeps the sibling row"
|
||||||
|
requirement: HTTP-01
|
||||||
|
verification:
|
||||||
|
- kind: unit
|
||||||
|
ref: "plugins/golem15/user#TestOAuthIdentitiesDestroyNoContentKeepsSibling"
|
||||||
|
status: pass
|
||||||
|
- kind: unit
|
||||||
|
ref: "plugins/golem15/fonoteka#TestOAuthTokenSurfaceIsolationCoverage/test_oauth_identity_routes_exist_on_jwt_surface_only"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: "Unrestricted /me emits collection_ids JSON null; three manifest routes are ported at 175/175/0"
|
||||||
|
requirement: API-09
|
||||||
|
verification:
|
||||||
|
- kind: e2e
|
||||||
|
ref: "parity#TestParityCorpus recorded 175/175 passing 175 failing 0 unrecorded 0 pending 0"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D5
|
||||||
|
description: "sm-user-plugin README names OAuthIdentitiesIndex/Destroy/Options as host-mounted constructors without a consuming-application name"
|
||||||
|
verification:
|
||||||
|
- kind: other
|
||||||
|
ref: "grep OAuthIdentitiesIndex plugins/golem15/user/README.md"
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
|
||||||
|
duration: 90min
|
||||||
|
completed: 2026-10-05
|
||||||
|
status: complete
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 14.1: OAuth identities and fonoteka me routes — Plan 01 Summary
|
||||||
|
|
||||||
|
**Shared-plugin OAuth identities table and host-mounted GET/DELETE, `/me` collection_ids JSON null, and the three orphan routes ported at 175/175/0**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 90 min
|
||||||
|
- **Started:** 2026-10-05T19:04:22Z
|
||||||
|
- **Completed:** 2026-10-05T19:24:44Z
|
||||||
|
- **Tasks:** 4
|
||||||
|
- **Files modified:** 20
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- `golem15_user_oauth_identities` ships in sm-user-plugin with the full PHP column set, gormigrate ID `202610050001_create_oauth_identities`, `lagoon.Encrypted` tokens, and Hidden `profile_data`.
|
||||||
|
- Host JWT group mounts `OAuthIdentitiesIndex` and `OAuthIdentitiesDestroy` (Winter HTML 404, DELETE `throttle:10,1`, unconstrained `{provider}`). User plugin `routes.go` is unchanged.
|
||||||
|
- Unrestricted `/me` emits `"collection_ids": null`; restricted `/me` still lists the pinned collection as `{{id:collection}}`.
|
||||||
|
- Extras `oauth-identities-linked` and `me-unrestricted` recorded from isolated PHP; corpus `recorded 175/175 passing 175 failing 0 unrecorded 0 pending 0`.
|
||||||
|
- README documents the exported constructors as host-mounted; it never names a consuming application.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Table ownership checkpoint** — no code commit (decision `ship-shared-full` answered before dispatch)
|
||||||
|
2. **Task 2: Tracer — table, Index, empty GET** — `63ac504` (sm-user-plugin feat), `1bed435` (fonoteka.go feat)
|
||||||
|
3. **Task 3: Destroy, 409 lang, JWT DELETE throttle** — `8e172c5` (sm-user-plugin feat), `696a35e` (fonoteka.go feat)
|
||||||
|
4. **Task 4: `/me` null, D-10 extras, ported 175, README** — `ac8aa16` (sm-user-plugin docs), `1584d73` (fonoteka.go feat)
|
||||||
|
|
||||||
|
**Plan metadata:** this SUMMARY commit
|
||||||
|
|
||||||
|
_Note: TDD was not applicable for this plan._
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `plugins/golem15/user/models/oauth_identity.go` — `OAuthIdentity`, `TableName`, Hidden secrets, empty Fillable
|
||||||
|
- `plugins/golem15/user/updates/202610050001_create_oauth_identities.go` — gormigrate up/down
|
||||||
|
- `plugins/golem15/user/controllers/oauth_identities.go` — Index/Destroy/Options
|
||||||
|
- `plugins/golem15/user/oauth_identities_test.go` — empty list and 204 sibling smokes
|
||||||
|
- `plugins/golem15/user/lang/{en,pl}/lang.yaml` — `oauth.last_method_blocked`
|
||||||
|
- `plugins/golem15/user/README.md` — table, constructors, migration, model
|
||||||
|
- `plugins/golem15/fonoteka/routes.go` — JWT GET/DELETE mounts
|
||||||
|
- `plugins/golem15/fonoteka/phase08_coverage_test.go` — jwt-only surfaces + DELETE throttle
|
||||||
|
- `plugins/golem15/fonoteka/controllers/api/me_token_controller.go` — D-09 null `collection_ids`
|
||||||
|
- `parity/manifest.yaml`, `parity_test.go`, `parity_contract_test.go`, seed/reset PHP+Go, recorded fixtures
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- **ship-shared-full** (Task 1, pre-dispatch): the table lives in sm-user-plugin with the full PHP column set. Locked D-01 and D-07.
|
||||||
|
- Identity HTTP is host-mounted; sm-user-plugin `/_user` routes stay unchanged.
|
||||||
|
- Last-method 409 uses identity count only (D-06).
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 3 - Blocking] Isolated PHP has no `user_api_tokens` table**
|
||||||
|
- **Found during:** Task 4 (PHP recording)
|
||||||
|
- **Issue:** `fonoteka_reset.php` wiped `user_api_tokens`; this Winter checkout still stores tokens in `golem15_fonoteka_api_tokens`, so tinker aborted before vars were written.
|
||||||
|
- **Fix:** Guard both token tables and `golem15_user_oauth_identities` with `Schema::hasTable` and wipe the fonoteka token table the PHP mint actually uses.
|
||||||
|
- **Files modified:** `../fonoteka.go/parity/fonoteka_reset.php`
|
||||||
|
- **Verification:** tinker `reset ok`; identities and unrestricted token rows present
|
||||||
|
- **Committed in:** `1584d73` (Task 4)
|
||||||
|
|
||||||
|
**2. [Rule 3 - Blocking] Restricted `/me` fixture used Phase 2 `{{id:token}}`**
|
||||||
|
- **Found during:** Task 4 (fonoteka seed_hook)
|
||||||
|
- **Issue:** The existing `/me` case was recorded from the genres bootstrap (`id:token` = rock). Under `seed_hook: fonoteka` that placeholder does not resolve.
|
||||||
|
- **Fix:** Re-recorded the case from a plain `PARITY_CASE=` tinker reset. Body is `collection_ids:[{{id:collection}}]`, `name` `parity-mcp`.
|
||||||
|
- **Files modified:** `../fonoteka.go/parity/fixtures/routes/GET__api_v1_fonoteka_me_personal_token.yaml`
|
||||||
|
- **Verification:** `TestParityCorpus` `recorded 175/175 passing 175 failing 0 unrecorded 0 pending 0`
|
||||||
|
- **Committed in:** `1584d73` (Task 4)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 2 auto-fixed (2 blocking)
|
||||||
|
**Impact on plan:** Both needed so PHP recording and Go replay share one seed. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
- First tinker died with `no such table: user_api_tokens` (deviation 1). Isolated PHP serve on 127.0.0.1:8423 stayed up; recording resumed after the guarded wipe.
|
||||||
|
- Tracer verified end-to-end — expanding (Task 2 automated verify; no human-verify checkpoint, HUMAN_VERIFY_MODE=end-of-phase).
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- Plan 14.1-02 can port `OAuthIdentityApiTest.php` (EN/PL 409, Winter 404s, 401 on `/google`, secret-leak, migration up/down) against this code.
|
||||||
|
- API-09 stays Pending until 14.1-02 SUMMARY exists (`requirements.ready-ids` shared-ID gate).
|
||||||
|
- Do not push sm-user-plugin or fonoteka.go (plan does not ask). Plugin HEAD `ac8aa16` is local-only.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 14.1-oauth-identities-and-fonoteka-me-routes*
|
||||||
|
*Completed: 2026-10-05*
|
||||||
@@ -99,5 +99,5 @@
|
|||||||
"label": "Advance to the next step",
|
"label": "Advance to the next step",
|
||||||
"reason": "Phase 14.1 of 22 · executing"
|
"reason": "Phase 14.1 of 22 · executing"
|
||||||
},
|
},
|
||||||
"updated_at": "2026-10-05T17:48:29.352Z"
|
"updated_at": "2026-10-05T19:04:22.107Z"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user