de30497f59
- Implemented tenant and user management features including: - Tenant creation and management with associated migrations. - User creation and management with associated migrations. - Tenant membership management with associated migrations. - Platform user roles management with associated migrations. - Quota management with associated migrations. - Article and template management with associated migrations. - Added HTTP handlers for templates and workspaces. - Created tests for protected and public routes. - Introduced a script to check tenant scope in SQL queries. - Documented task plan for backend completion and frontend foundation.
13 KiB
13 KiB
Findings & Decisions
Requirements
- Verify the repository against the 9-step implementation plan provided by the user.
- Use
/Users/liangxu/Documents/test/geo-rankly/docs/superpowers/specs/2026-03-31-admin-web-backend-core-design.mdas the source of truth for the next development slice. - Continue development immediately after identifying the earliest unfinished step.
Research Findings
- The repository already contains core backend scaffolding under
server/, includingcmd/tenant-api,internal/bootstrap,shared,tenant,migrations, and SQL query files. server/Makefilealready definesdev-init,dev-api,migrate-up,sqlc-generate,seed,lint, andtest.- The bootstrap layer already exposes
/api/health/liveand/api/health/ready. - The design doc defines a sequential 9-step delivery plan and expects
sqlcgenerated code underinternal/tenant/repository/generated/, plus repository wrappers around it. - The repository has 19 migration
.up.sqlfiles, matching the plan's schema count, andcmd/dev-seedseedsadmin@geo.localplus plan/quota/template data. internal/tenant/repository/currently contains only query SQL,sqlc.yaml,tx.go, and placeholder integration tests; there is nogenerated/directory and no repository wrapper implementations.auth_service.go,workspace_service.go,template_service.go,article_service.go, andbrand_service.gostill issue SQL directly againstpgxpool.Pool, which contradicts the design doc's Step 4 target.- Running
make sqlc-generatecurrently fails becauseserver/internal/tenant/repository/sqlc.yamlsetsschema: "../../migrations/", which resolves to a non-existent path. The correct repository-relative path should point toserver/migrations. - After fixing
sqlc.yaml,make sqlc-generatesucceeds and produces typed code inserver/internal/tenant/repository/generated/. - Repository wrappers now exist for auth, workspace, template, article, quota, and audit queries, and the auth/workspace/template services consume them on the main code path.
- Refresh token rotation is now atomic in Redis via a Lua script in
session_store.go, with tests covering successful rotation and hash mismatch rejection. make testandmake lintboth pass locally after cleaning up existing lint violations.- A GitHub Actions workflow now exists at
.github/workflows/backend-ci.yml; it runssqlcgeneration, verifies generated code is committed, executes the tenant SQL scope guard, runs tests, and runsgolangci-lint. - The
server/Makefilenow exposestenant-scope-guard, so the tenant filter check is available both locally and in CI. - The
server/Makefileno longer depends on a preinstalledmigratebinary; it now runsgolang-migrateviago run -tags postgres, which allowedmake dev-initto run successfully on this machine. make dev-initnow completes end-to-end: Docker services start, all 19 migrations apply, and seed data creates tenant/user/plan/template records.- Runtime verification succeeded for
/api/health/live,/api/health/ready,POST /api/auth/login,GET /api/auth/me,POST /api/auth/refresh, andPOST /api/auth/logout. - Negative auth checks also passed at runtime: the old access token returns
40103 token_revokedafter logout, and the old refresh token returns40121 refresh_session_expiredafter rotation. - Workspace runtime verification passed for all four first-screen endpoints:
overview,recent-articles,quota-summary, andtemplate-cards. - Template generation runtime verification passed end-to-end: creating a generation task produced an article, article detail returned
generate_status=completed, article versions returned one version, and quota balance decreased from 100 to 99. - Brand runtime verification passed for create keyword/question/competitor flows, question version history returned two versions after update, and soft-deleted brands can be recreated with the same name.
- The repository still has no
apps/orpackages/directories, so neitheradmin-webnorops-admin-webhas been started. - The frontend architecture doc recommends
pnpm workspace + Vue 3 + TypeScript + ant-design-vue + Vite, with shared packages for UI, shared DTOs, HTTP client, and TS config. - The current backend already exposes enough stable endpoints for a first
admin-webslice:POST /api/auth/login,GET /api/auth/me, and the four workspace endpoints under/api/tenant/workspace/*. - Backend responses use a consistent envelope:
code,message,data, andrequest_id, which makes a shared frontend API client straightforward. - Local toolchain support for the frontend is present on this machine:
node v22.20.0,npm 10.9.3, andpnpm 10.28.2. - A new pnpm workspace now exists at the repo root, with
apps/admin-webplus shared packages underpackages/shared-types,packages/http-client, andpackages/tsconfig. apps/admin-webis now a working Vue 3 + TypeScript + Vite 8 app with Ant Design Vue, Pinia, Vue Router, and Vue Query wired in.- The frontend implements a persistent auth session store, login flow, route guard, auto-refresh-capable API client, and a tenant-facing application shell.
- The workspace page is wired to live backend data through the four dashboard endpoints and renders template cards, stats, quota, and recent articles.
- Placeholder routes now exist for template creation, custom generation, optimization, media, brands, tracking, and knowledge so the navigation shell is ready for incremental page delivery.
pnpm build:adminpasses successfully, producing a production build underapps/admin-web/dist/.- Static preview verification passed via
vite previewand HTTP checks againsthttp://127.0.0.1:4173/login, which returnedHTTP/1.1 200 OKplus the built asset references. - Gemini CLI was tested but then abandoned for this turn:
gemini-3.1-pro-previewconsistently returned429 MODEL_CAPACITY_EXHAUSTED, and the user explicitly requested not to use Gemini afterward. - After the user indicated Playwright was fixed, browser-level verification succeeded through the Playwright CLI path rather than the broken MCP path.
- Browser testing exposed one real frontend bug: the login CTA rendered correctly but did not submit the form on click until it was explicitly bound to
handleSubmit. - After the login-button fix, a Playwright end-to-end flow successfully loaded
/login, signed in with the seeded account, reached/workspace, and verified the presence of the workspace heading plus the template and recent-content sections. - The production bundle size improved substantially after switching Ant Design Vue registration from full-plugin mode to per-component registration; the main JS chunk dropped from roughly
1.4 MBto about747 kBbefore gzip. - The currently exposed tenant-facing backend interfaces fall into four frontend-covered groups: auth, workspace, templates/articles, and brands.
- The reference screenshots were re-read using position-aware OCR extraction, which made the layout intent clear beyond the raw text labels.
docs/refer/工作台.pngplaces the main content in a left-heavy column with template cards above recent articles, while the right side holds the compact stats cluster; the quota/plan card sits in the left sidebar footer rather than the main canvas.docs/refer/模板创作.pnguses a top page hero, a horizontal filter/action strip, an article table below it, and a separate template-selection layer before entering a 3-step generation flow.docs/refer/文擎GEO/模版创作-新建模版-创建topx文章-步骤一.pngand...步骤二.pngshow the generation flow as a wizard: step 1 basic info plus brand/keyword/competitor context, step 2 title and structure selection, step 3 generation.docs/refer/品牌词库.pnguses a top brand card rail, then a split content area with keyword navigation on the left and question management on the right; the competitor library lives under a sibling tab.docs/refer/媒体管理.pngconfirms the overall visual system: page hero under the content header, three-step guide card near the top, and white cards on a cool gray background with the same left navigation shell.- The user explicitly asked for i18n and styling discipline during implementation: text should move behind translation keys, and component styles should live in
<style>blocks rather than inline attributes. pnpm dev:adminregressed temporarily after the route graph referenced a missingBrandsView.vue; adding the missing view, installing the new frontend dependency set, and rerunning checks restored the Vite startup path.pnpm typecheck:adminnow passes after introducing the i18n scaffold, restoringAppShell.vueto the user's preferred version, and removing inline styles from the Vue SFC templates.
Technical Decisions
| Decision | Rationale |
|---|---|
| Verify by code inspection first, then run targeted commands | Faster way to establish step coverage before making changes |
| Use the design doc as the acceptance reference when repository behavior is ambiguous | User explicitly pointed to this document for next-step development |
| Treat Step 4 as the current development target unless command verification disproves it | Earlier steps have visible artifacts, but repository/sqlc acceptance is not yet met |
Fix sqlc generation and introduce repository wrappers before touching later roadmap items |
This is the first broken acceptance gate and an architectural dependency for the service layer |
| Close Step 9 by adding repository-scoped CI rather than a repo-wide generic pipeline | The remaining missing acceptance item was backend CI plus the tenant scope guard |
Resume into admin-web instead of ops-admin-web |
Only tenant-facing APIs exist in the repository today, so this is the only frontend slice that can be meaningfully wired end to end |
| Keep the initial frontend page set broad in navigation but shallow in implementation | This gives the repo a usable admin shell now without inventing missing backend modules for later pages |
| Use templates/articles and brands as the primary implementation targets for this turn | They are the remaining backend-backed pages still missing real frontend coverage |
| Use screenshot-derived spatial structure as an implementation constraint | Needed to satisfy the user's requirement to follow layout and placement, not just labels |
Introduce a minimal vue-i18n foundation now instead of leaving hard-coded strings in new pages |
The user explicitly called out the current i18n approach as non-standard |
Keep AppShell.vue on the user-preferred version and avoid structural/style rewrites there |
The user said that file is managed elsewhere and only allowed inline-style cleanup |
Issues Encountered
| Issue | Resolution |
|---|---|
| Repository is fully untracked in git status output | Avoid relying on git history; verify via filesystem and test commands instead |
make sqlc-generate fails before any code is generated |
Repair the sqlc.yaml schema path and then build repository wrappers around generated queries |
go run migrate initially failed with unknown driver postgres |
Added -tags postgres to the Makefile-managed migrate command |
Playwright MCP could not open a browser session locally because it tried to create /.playwright-mcp |
Use vite preview plus curl verification for this turn instead of spending time on browser tool plumbing |
Resources
/Users/liangxu/Documents/test/geo-rankly/docs/superpowers/specs/2026-03-31-admin-web-backend-core-design.md/Users/liangxu/Documents/test/geo-rankly/server/Makefile/Users/liangxu/Documents/test/geo-rankly/server/cmd/tenant-api/main.go/Users/liangxu/Documents/test/geo-rankly/server/internal/bootstrap/bootstrap.go/Users/liangxu/Documents/test/geo-rankly/server/internal/shared/auth/session_store.go/Users/liangxu/Documents/test/geo-rankly/server/internal/tenant/repository/sqlc.yaml/Users/liangxu/Documents/test/geo-rankly/server/scripts/check_tenant_scope.sh/Users/liangxu/Documents/test/geo-rankly/.github/workflows/backend-ci.yml/Users/liangxu/Documents/test/geo-rankly/server/docker-compose.yaml/Users/liangxu/Documents/test/geo-rankly/apps/admin-web/Users/liangxu/Documents/test/geo-rankly/packages/shared-types/src/index.ts/Users/liangxu/Documents/test/geo-rankly/packages/http-client/src/index.ts
Visual/Browser Findings
- Reviewed the reference screenshots for
工作台.pngand模板创作.pngand matched the new UI to the same left-nav plus airy card/table composition. - Browser automation verification was attempted but blocked by the local Playwright MCP directory error; preview HTTP verification succeeded instead.
- Later browser verification succeeded with Playwright CLI, and the captured login/workspace screenshots matched the intended layout and data density.
- Position-aware OCR of the reference images confirmed the sidebar navigation occupies roughly the left 10-12% of the frame, with content titles aligned at the upper-left of the main canvas and most action buttons aligned to the right edge of page headers.
- The workspace screenshot places stats on the upper-right and the recent-articles table directly beneath the template card block, so the existing all-grid treatment should be tightened into a more asymmetric two-column composition.