From 8a18202878ed0bb162fc921fcfcde6afd3c9572b Mon Sep 17 00:00:00 2001 From: rain Date: Sat, 11 Jul 2026 09:36:02 +0800 Subject: [PATCH] docs: record auth profile flow --- ...api-page-integration-tracker-2026-07-09.md | 24 +- .../plans/2026-07-11-auth-to-profile-flow.md | 474 ++++++++++++++++++ .../2026-07-11-auth-to-profile-flow-design.md | 2 +- 3 files changed, 496 insertions(+), 4 deletions(-) create mode 100644 docs/superpowers/plans/2026-07-11-auth-to-profile-flow.md diff --git a/docs/pc-api-page-integration-tracker-2026-07-09.md b/docs/pc-api-page-integration-tracker-2026-07-09.md index 4838781..b9efbbf 100644 --- a/docs/pc-api-page-integration-tracker-2026-07-09.md +++ b/docs/pc-api-page-integration-tracker-2026-07-09.md @@ -2,10 +2,16 @@ 创建时间:2026-07-09 15:14:58 +08:00 接口依据:`genealogy-pc-openapi.yaml` -接口基础地址:`http://test-genealogy-api.ddxcjp.cn` +接口基础地址:`http://182.61.18.23:8080` 旧依据处理:`APP.openapi.json` 只作为历史误用记录,不再作为 PC 页面继续对接依据。 旧进度记录:`docs/api-page-integration-tracker-2026-07-09.md` +## 当前地址契约 + +- 运行时唯一来源:根目录 `config.js`。 +- 当前开发和生产地址:`http://182.61.18.23:8080`。 +- 地址变更记录:2026-07-11 已由历史测试域名切换为当前 IP 和端口;文档中出现的 `test-genealogy-api.ddxcjp.cn` 仅用于描述历史事件,不代表当前运行时配置。 + ## 执行规则 1. 所有 PC 接口对接必须先进入本追踪表,再改代码。 @@ -29,7 +35,7 @@ 分析文件:`genealogy-pc-openapi.yaml` 1. `paths` 中实际存在 25 个接口操作,分为验证码、PC 认证、PC 文件、行政区划四类。 -2. `servers` 仍是本地地址示例,项目实际对接基础地址继续按用户指定使用 `https://test-genealogy-api.ddxcjp.cn`。 +2. `servers` 仍是本地地址示例;当前运行时基础地址以 `config.js` 为准,为 `http://182.61.18.23:8080`。 3. 登录后接口使用 `Authorization` 作为 token header,同时所有 PC 认证和文件接口都要求 header `clientid`;用户最新提供的 PC `clientid` 为 `ced7e5f0498645c6ec642dcf450b036f`,客户端 Key 为 `web_pc`。 4. `components.tags` 和 `components.schemas/requestBodies` 中出现家谱、动态、世系、字辈等业务模型,但 `paths` 没有对应接口路径;实现时不能把这些 schema 当成可调用 PC 接口。 5. 验证码 schema 示例里仍出现 `APP_LOGIN`、`PC_LOGIN` 等文本示例;实际页面场景以后台配置为准,当前明确可用的 PC/H5 场景为 `WEB_H5_LOGIN`、`WEB_H5_REGISTER`、`WEB_H5_FORGOT_PASSWORD`。 @@ -67,7 +73,7 @@ | PC-007 | 复核通过 | 实施规划 | `genealogy-pc-openapi.yaml` | 当前计划与 YAML `paths` 一致,不使用旧 APP 路径 fallback。 | | PC-008 | 复核通过 | PC YAML 未覆盖业务页面 | `PC_API_NOT_AVAILABLE` | `utils/ApiClient.js` 统一抛 `PC_API_NOT_AVAILABLE`,旧 `/genealogy/app/` 请求路径扫描无结果。 | | PC-009 | 本地复核通过 | 登录、注册、找回密码 | PC auth、`/captcha/*` | 三页场景编码、表单契约、Axios 请求客户端和相关测试均通过;真实账号流程待业务数据联调。 | -| PC-010 | 复核通过(网关可达) | `config.js`、`utils/ApiClient.js` | 测试 API 基础地址 | 开发地址为 `http://test-genealogy-api.ddxcjp.cn`;2026-07-10 10:02:48 +08:00 外部 `curl.exe -I` 返回 `HTTP 200 OK`。 | +| PC-010 | 已复核(当前地址已同步) | `config.js`、`tests/config.test.js`、`utils/ApiClient.js` | API 基础地址 | 当前开发和生产地址均为 `http://182.61.18.23:8080`;地址唯一运行时来源为 `config.js`,`tests/config.test.js` 已同步断言。 | | PC-011 | 本地复核通过 | 三张认证页 TAC 弹窗 | `public/tac`、`/captcha/*` | 页面级挂载、移动端约束和结构测试通过;未修改 `tac.min.js`。 | ## PC 页面覆盖矩阵草案 @@ -291,3 +297,15 @@ - 修改文件:`public/js/captcha-pages.js`、`tests/captcha-pages.test.js`、`docs/superpowers/plans/2026-07-10-tac-layer-real-mount-fix.md`、`docs/pc-api-page-integration-tracker-2026-07-09.md` - 修改结果:`createCaptchaLayer` 现在用字符串 `content` 让 Layui 创建 `
`,弹层打开后再通过 `document.querySelector` 获取这个实际节点,并将它作为 TAC 的 `bindEl`。未修改 `public/tac`,未新增验证码 CSS,未传 TAC 视觉配置。 - 验证结果:先运行 `node tests\captcha-pages.test.js` 复现失败;修复后 `node tests\auth-page-structure.test.js`、`node tests\captcha-pages.test.js`、`node --check public\js\captcha-pages.js` 和 `git diff --check` 通过。`git diff --check` 仅输出既有 CRLF 行尾提示,没有空白错误。 + +## PC-025 注册、登录到个人资料闭环 + +- 状态:已完成 +- 完成时间:2026-07-11 09:32:35 +08:00 +- 规划文件:`docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md` +- 页面范围:`register.html`、`login.html`、`profile.html`、`profile-data.html` +- 接口范围:`/genealogy/pc/auth/register`、`/genealogy/pc/auth/login`、`/genealogy/pc/auth/login/sms`、`/genealogy/pc/auth/profile`、`/genealogy/pc/auth/logout` +- 地址契约:运行时唯一来源为 `config.js`;当前开发和生产地址均为 `http://182.61.18.23:8080`。 +- 流程结果:注册成功清除 token 并跳转 `login.html`;密码和短信登录必须取得 token 后跳转 `profile.html`;个人资料无 token 或收到 HTTP/业务 `401` 时清 token 并跳转 `index.html`;确认退出无论接口结果都清 token 并跳转 `index.html`。 +- 修改文件:`tests/config.test.js`、`tests/utils.test.js`、`utils/ApiClient.js`、`tests/api-client.test.js`、`public/js/profile-pages.js`、`public/js/profile-common.js`、`profile.html`、`tests/profile-pages.test.js`、`tests/profile-logout-structure.test.js`。 +- 验证结果:`node tests/config.test.js`、`node tests/utils.test.js`、`node tests/api-client.test.js`、`node tests/auth-pages.test.js`、`node tests/profile-pages.test.js`、`node tests/profile-logout-structure.test.js`、`node --check utils/ApiClient.js`、`node --check public/js/profile-pages.js`、`node --check public/js/profile-common.js` 和全量 Node 测试均通过。 diff --git a/docs/superpowers/plans/2026-07-11-auth-to-profile-flow.md b/docs/superpowers/plans/2026-07-11-auth-to-profile-flow.md new file mode 100644 index 0000000..83d51d9 --- /dev/null +++ b/docs/superpowers/plans/2026-07-11-auth-to-profile-flow.md @@ -0,0 +1,474 @@ +# Auth To Profile Flow Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Complete the PC registration, login, profile, unauthorized, logout, and endpoint-address flow with one token owner and deterministic redirects. + +**Architecture:** `config.js` remains the sole runtime owner of the API base address. `utils/ApiClient.js` owns token validation, persistence, and cleanup; `profile-pages.js` decides whether a profile request is allowed and redirects unauthenticated users to the homepage; `profile-common.js` delegates confirmed logout to the API client. The integration tracker records the current address and verified behavior only after verification commands complete. + +**Tech Stack:** Browser JavaScript (UMD and jQuery), Axios, Node.js `assert` tests, static HTML, Markdown. + +## Global Constraints + +- The current API base address is `http://182.61.18.23:8080` for development and production, and `config.js` is its only runtime owner. +- Runtime-related tests use the same address; only documents explicitly marked historical may retain the former test domain. +- Successful registration clears `genealogy_auth_token` and redirects to `login.html`; it never persists a registration response token. +- Only successful password or SMS login with a nonempty response token persists `genealogy_auth_token` and redirects to `profile.html`. +- `profile.html` and `profile-data.html` redirect to `index.html` before a profile request when no token exists, and after HTTP or business `401` responses. +- Confirmed logout requests `/genealogy/pc/auth/logout`, clears the token regardless of the request outcome, and redirects to `index.html`. +- Do not add global Axios redirects, duplicate token storage in pages, alter API paths, or change password-reset, phone-change, account-deactivation, or profile pages that do not load the profile API. + +--- + +### Task 1: Synchronize the configured API address test + +**Files:** +- Modify: `tests/config.test.js:11-28` +- Modify: `tests/utils.test.js:31` + +**Interfaces:** +- Consumes: `configFactory(...).getConfig()` and `getApiBaseUrl()` from `config.js`. +- Produces: a test that asserts the current `config.js` address for both environments. + +- [ ] **Step 1: Confirm the existing address-contract test fails** + +The current test contains these stale assertions: + +```js +assert.deepStrictEqual(developmentConfig.getConfig(), { + environment: 'development', + apiBaseUrl: 'http://test-genealogy-api.ddxcjp.cn' +}); + +assert.strictEqual(productionConfig.getApiBaseUrl(), 'http://test-genealogy-api.ddxcjp.cn'); +``` + +Run: `node tests/config.test.js` + +Expected: failure because `config.js` already returns `http://182.61.18.23:8080`. + +- [ ] **Step 2: Update the stale test expectations** + +Replace the two expected URL values with: + +```js +assert.deepStrictEqual(developmentConfig.getConfig(), { + environment: 'development', + apiBaseUrl: 'http://182.61.18.23:8080' +}); + +assert.strictEqual(productionConfig.getApiBaseUrl(), 'http://182.61.18.23:8080'); +``` + +Replace the mocked requester address in `tests/utils.test.js` with: + +```js + baseUrl: 'http://182.61.18.23:8080', +``` + +- [ ] **Step 3: Run the focused configuration test** + +Run: `node tests/config.test.js` + +Expected: `config tests passed`. + +Run: `node tests/utils.test.js` + +Expected: `utils tests passed`. + +- [ ] **Step 4: Commit the address-test synchronization** + +```powershell +git add -- tests/config.test.js tests/utils.test.js +git commit -m "test: sync configured api address" +``` + +### Task 2: Enforce login-token and logout-cleanup contracts + +**Files:** +- Modify: `utils/ApiClient.js:52-60, 167-191, 270-274` +- Modify: `tests/api-client.test.js:83-177` + +**Interfaces:** +- Consumes: `getTokenFromResponse(data)`, `setToken(token)`, `clearToken()`, and public `client.login`, `client.loginBySms`, and `client.logout` methods. +- Produces: `client.login(body)` and `client.loginBySms(body)` reject with `ApiError('登录响应缺少 token')` when their response has no token; `client.logout()` clears the configured token key before resolving or rejecting. + +- [ ] **Step 1: Write failing API-client assertions** + +Append this after the registration assertions and before `client.sendSmsCode(...)` in `tests/api-client.test.js`: + +```js + const missingTokenStore = createStore(); + const missingTokenClient = GenealogyApi.createClient({ + baseUrl: 'http://182.61.18.23:8080', + clientId: 'client-x', + tenantId: 'tenant-x', + tokenKey: 'token-key', + tokenStore: missingTokenStore, + axiosInstance: { + request: async () => ({ + status: 200, + data: { code: 200, data: {} } + }) + } + }); + await assert.rejects( + missingTokenClient.login({ phone: '13800000000', password: 'md5' }), + (error) => error.message === '登录响应缺少 token' + ); + assert.strictEqual(missingTokenStore.getItem('token-key'), null); + + store.setItem('token-key', 'logout-token'); + await client.logout(); + assert.strictEqual(calls[9].url, '/genealogy/pc/auth/logout'); + assert.strictEqual(store.getItem('token-key'), null); + + const failedLogoutStore = createStore({ + 'token-key': 'logout-token' + }); + const failedLogoutClient = GenealogyApi.createClient({ + baseUrl: 'http://182.61.18.23:8080', + clientId: 'client-x', + tenantId: 'tenant-x', + tokenKey: 'token-key', + tokenStore: failedLogoutStore, + axiosInstance: { + request: async () => { + throw new Error('logout failed'); + } + } + }); + await assert.rejects(failedLogoutClient.logout(), /logout failed/); + assert.strictEqual(failedLogoutStore.getItem('token-key'), null); +``` + +Move the existing SMS-code assertions from `calls[9]` to `calls[10]` and change the final call-count assertion from `10` to `11`. + +Replace the two existing `baseUrl: 'https://test-genealogy-api.ddxcjp.cn'` fixtures in this file with: + +```js + baseUrl: 'http://182.61.18.23:8080', +``` + +- [ ] **Step 2: Run the focused API-client test and confirm failure** + +Run: `node tests/api-client.test.js` + +Expected: failure at the missing-token rejection because the current login method resolves without writing a token, before reaching the logout assertions. + +- [ ] **Step 3: Add the minimal token validation and logout cleanup** + +Add this helper after `getTokenFromResponse` in `utils/ApiClient.js`: + +```js + function requireLoginToken(data) { + var token = getTokenFromResponse(data); + + if (!token) throw new ApiError('登录响应缺少 token'); + return token; + } +``` + +Replace the token writes in `login()` and `loginBySms()` with: + +```js + setToken(requireLoginToken(data)); +``` + +Replace `logout` with: + +```js + logout: async function () { + try { + return await request('DELETE', '/genealogy/pc/auth/logout'); + } finally { + clearToken(); + } + }, +``` + +- [ ] **Step 4: Run the API-client test and confirm all token paths pass** + +Run: `node tests/api-client.test.js` + +Expected: `api-client tests passed`. + +- [ ] **Step 5: Commit the API-client contract** + +```powershell +git add -- utils/ApiClient.js tests/api-client.test.js +git commit -m "fix: complete auth token lifecycle" +``` + +### Task 3: Guard profile access and connect confirmed logout + +**Files:** +- Modify: `public/js/profile-pages.js:18-22, 165-198` +- Modify: `public/js/profile-common.js:9-82` +- Modify: `profile.html:80, 355` +- Modify: `tests/profile-pages.test.js:1-65` +- Create: `tests/profile-logout-structure.test.js` + +**Interfaces:** +- Consumes: public `api.getToken()`, `api.clearToken()`, `api.currentProfile()`, `api.updateProfile()`, and `api.logout()` methods. +- Produces: `ProfilePages.shouldRedirectToHome(api, error)` for token and unauthorized classification; profile reads and writes redirect to `index.html` when that helper returns true; the existing logout controls call `api.logout()` before navigating to `index.html`. + +- [ ] **Step 1: Write failing profile and logout tests** + +Add these assertions before the final `console.log` in `tests/profile-pages.test.js`: + +```js + assert.strictEqual(ProfilePages.shouldRedirectToHome({ + getToken: () => '' + }), true); + assert.strictEqual(ProfilePages.shouldRedirectToHome({ + getToken: () => 'token-x' + }), false); + assert.strictEqual(ProfilePages.shouldRedirectToHome({ + getToken: () => 'token-x' + }, { status: 401 }), true); + assert.strictEqual(ProfilePages.shouldRedirectToHome({ + getToken: () => 'token-x' + }, { code: 401 }), true); + assert.strictEqual(ProfilePages.shouldRedirectToHome({ + getToken: () => 'token-x' + }, { status: 500 }), false); +``` + +Create `tests/profile-logout-structure.test.js` with: + +```js +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const profileHtml = fs.readFileSync(path.join(__dirname, '..', 'profile.html'), 'utf8'); +const profileCommon = fs.readFileSync(path.join(__dirname, '..', 'public', 'js', 'profile-common.js'), 'utf8'); + +assert.match(profileHtml, /data-logout-confirm/); +assert.match(profileHtml, //); +assert.match(profileCommon, /function performLogout\(targetUrl\)/); +assert.match(profileCommon, /api\.logout\(\)/); +assert.match(profileCommon, /targetUrl \|\| 'index\.html'/); + +console.log('profile logout structure tests passed'); +``` + +- [ ] **Step 2: Run the new focused tests and confirm failure** + +Run: `node tests/profile-pages.test.js` + +Expected: failure because `shouldRedirectToHome` is not exported. + +Run: `node tests/profile-logout-structure.test.js` + +Expected: failure because the logout confirmation markup and `performLogout` function do not exist. + +- [ ] **Step 3: Add profile token guard and unauthorized redirect** + +Add these helpers after `getApi()` in `public/js/profile-pages.js`: + +```js + function shouldRedirectToHome(api, error) { + var status = error && (error.status || error.code); + + return !api || !api.getToken || !api.getToken() || Number(status) === 401; + } + + function redirectToHome() { + if (!root.location) return; + if (typeof root.location.replace === 'function') { + root.location.replace('index.html'); + return; + } + root.location.href = 'index.html'; + } + + function redirectUnauthorized(api, error) { + if (!shouldRedirectToHome(api, error)) return false; + if (api && api.clearToken) api.clearToken(); + redirectToHome(); + return true; + } +``` + +Replace the existing combined early-return condition in `loadProfile()` with these two branches: + +```js + if (!api || !documentRef || !documentRef.querySelector('[data-profile-page]')) return; + if (redirectUnauthorized(api)) return; +``` + +Update its `catch` block to start with: + +```js + if (redirectUnauthorized(api, error)) return; +``` + +Update `submitProfileForm()` to place `if (redirectUnauthorized(api)) return;` after its existing null guard, and to start its `catch` block with `if (redirectUnauthorized(api, error)) return;` before setting an error status or message. + +Export the classifier with the existing public methods: + +```js + shouldRedirectToHome: shouldRedirectToHome, +``` + +- [ ] **Step 4: Connect both logout confirmations to the API client** + +Add this function before `bindLogout()` in `public/js/profile-common.js`: + +```js + function performLogout(targetUrl) { + var api = window.GenealogyApi && window.GenealogyApi.defaultClient; + var redirect = function () { + window.location.href = targetUrl || 'index.html'; + }; + + if (!api || !api.logout) { + redirect(); + return; + } + + api.logout().catch(function () {}).then(redirect); + } +``` + +In `bindLogout()`, change the default target URL to `index.html`, replace the Layui confirmation callback body with `performLogout(targetUrl);`, and add this event handler before the existing `[data-logout-close]` handler: + +```js + $(document).on('click', '[data-logout-confirm]', function (event) { + event.preventDefault(); + closeLegacyLogout(); + performLogout($(this).attr('href') || 'index.html'); + }); +``` + +In `profile.html`, change the legacy confirmation anchor to: + +```html +确认退出 +``` + +- [ ] **Step 5: Run the focused profile tests and syntax checks** + +Run: `node tests/profile-pages.test.js` + +Expected: `profile-pages tests passed`. + +Run: `node tests/profile-logout-structure.test.js` + +Expected: `profile logout structure tests passed`. + +Run: `node --check public/js/profile-pages.js` + +Expected: exit code `0`. + +Run: `node --check public/js/profile-common.js` + +Expected: exit code `0`. + +- [ ] **Step 6: Commit the profile and logout flow** + +```powershell +git add -- public/js/profile-pages.js public/js/profile-common.js profile.html tests/profile-pages.test.js tests/profile-logout-structure.test.js +git commit -m "fix: guard profile auth and logout" +``` + +### Task 4: Record the current flow and run end-to-end regression checks + +**Files:** +- Modify: `docs/pc-api-page-integration-tracker-2026-07-09.md:1-9, 32, 70, 163` +- Modify: `docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md:3-5` + +**Interfaces:** +- Consumes: the verified results of Tasks 1 through 3. +- Produces: a tracker whose current address and authentication-flow status match the code and tests, and a spec marked approved for implementation. + +- [ ] **Step 1: Run all focused flow tests** + +Run: + +```powershell +node tests/config.test.js +node tests/api-client.test.js +node tests/auth-pages.test.js +node tests/profile-pages.test.js +node tests/profile-logout-structure.test.js +``` + +Expected: each command prints its success message and exits with code `0`. + +- [ ] **Step 2: Run syntax and complete regression checks** + +Run: + +```powershell +node --check utils/ApiClient.js +node --check public/js/profile-pages.js +node --check public/js/profile-common.js +Get-ChildItem -Path tests -Filter *.test.js | ForEach-Object { & node $_.FullName; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } } +``` + +Expected: all syntax checks exit `0`; every test script prints its success message; PowerShell exits `0` on the first test failure instead of masking it. + +- [ ] **Step 3: Update the tracker from verified evidence** + +At the top of `docs/pc-api-page-integration-tracker-2026-07-09.md`, replace the active base-address line with: + +```markdown +接口基础地址:`http://182.61.18.23:8080` +``` + +Add this section immediately after the introductory historical-record lines: + +```markdown +## Current Endpoint Contract + +- Runtime owner: `config.js`. +- Current development and production address: `http://182.61.18.23:8080`. +- Address change record: on 2026-07-11 the active address changed from the historical test domain to this IP address and port. Historical references to `test-genealogy-api.ddxcjp.cn` do not describe the current runtime configuration. +``` + +Replace the YAML-analysis item that says the project currently uses the test domain with: + +```markdown +2. `servers` 仍是本地地址示例;当前运行时基础地址以 `config.js` 为准,为 `http://182.61.18.23:8080`。 +``` + +Replace the PC-010 row with: + +```markdown +| PC-010 | 已复核(当前地址已同步) | `config.js`、`tests/config.test.js`、`utils/ApiClient.js` | API 基础地址 | 当前开发和生产地址均为 `http://182.61.18.23:8080`;地址唯一运行时来源为 `config.js`,`tests/config.test.js` 已同步断言。 | +``` + +After Steps 1 and 2 pass, run `Get-Date -Format "yyyy-MM-dd HH:mm:ss K"` and insert its output as the `完成时间` line immediately after the `状态` line in this record. Append the rest of this record after the existing PC entries: + +```markdown +## PC-025 注册、登录到个人资料闭环 + +- 状态:已完成 +- 规划文件:`docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md` +- 页面范围:`register.html`、`login.html`、`profile.html`、`profile-data.html` +- 接口范围:`/genealogy/pc/auth/register`、`/genealogy/pc/auth/login`、`/genealogy/pc/auth/login/sms`、`/genealogy/pc/auth/profile`、`/genealogy/pc/auth/logout` +- 地址契约:运行时唯一来源为 `config.js`;当前开发和生产地址均为 `http://182.61.18.23:8080`。 +- 流程结果:注册成功清除 token 并跳转 `login.html`;密码和短信登录必须取得 token 后跳转 `profile.html`;个人资料无 token 或收到 HTTP/业务 `401` 时清 token 并跳转 `index.html`;确认退出无论接口结果都清 token 并跳转 `index.html`。 +- 修改文件:`tests/config.test.js`、`utils/ApiClient.js`、`tests/api-client.test.js`、`public/js/profile-pages.js`、`public/js/profile-common.js`、`profile.html`、`tests/profile-pages.test.js`、`tests/profile-logout-structure.test.js`。 +- 验证结果:`node tests/config.test.js`、`node tests/api-client.test.js`、`node tests/auth-pages.test.js`、`node tests/profile-pages.test.js`、`node tests/profile-logout-structure.test.js`、三个 `node --check` 命令和全量 Node 测试均通过。 +``` + +Change the spec status body to: + +```markdown +Approved for implementation. +``` + +- [ ] **Step 4: Check final whitespace and commit the record** + +Run: `git diff --check` + +Expected: exit code `0`; pre-existing CRLF conversion warnings are not whitespace errors. + +```powershell +git add -- docs/pc-api-page-integration-tracker-2026-07-09.md docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md +git commit -m "docs: record auth profile flow" +``` diff --git a/docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md b/docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md index 3fd9127..cf80970 100644 --- a/docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md +++ b/docs/superpowers/specs/2026-07-11-auth-to-profile-flow-design.md @@ -2,7 +2,7 @@ ## Status -Pending written-spec review. +Approved for implementation. ## Goal