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.
266 lines
18 KiB
Markdown
266 lines
18 KiB
Markdown
# Progress Log
|
|
|
|
## Session: 2026-03-31
|
|
|
|
### Phase 10: Interface Coverage Audit & Visual Mapping
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Re-read the backend router and transport/app layers to inventory every currently exposed tenant-facing HTTP interface.
|
|
- Confirmed the remaining frontend-backed API groups are `templates/articles` and `brands`, while `custom/media/tracking/knowledge` still lack matching backend routes in this repo.
|
|
- Recovered the reference screenshot layouts with position-aware OCR so the implementation can follow actual placement and grouping instead of just textual labels.
|
|
- Files created/modified:
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 11: Admin-Web Full Interface Delivery
|
|
- **Status:** in_progress
|
|
- Actions taken:
|
|
- Added a minimal `vue-i18n` setup with `zh-CN` and `en-US` message bundles, locale persistence, and Ant Design locale switching.
|
|
- Reworked `LoginView`, `WorkspaceView`, `TemplatesView`, `ArticleDetailDrawer`, `TemplateGenerationDrawer`, `PageHero`, and `BrandsView` to stop using inline styles and to use component-local `<style>` blocks.
|
|
- Restored `AppShell.vue` to the user-preferred version and only moved its inline style attributes into named classes.
|
|
- Fixed the broken `pnpm dev:admin` startup path by adding the missing `BrandsView.vue`, running `pnpm install`, and re-running `pnpm typecheck:admin` plus `pnpm dev:admin`.
|
|
- Files created/modified:
|
|
- `apps/admin-web/package.json` (updated)
|
|
- `apps/admin-web/src/i18n/index.ts` (created)
|
|
- `apps/admin-web/src/i18n/messages/zh-CN.ts` (created)
|
|
- `apps/admin-web/src/i18n/messages/en-US.ts` (created)
|
|
- `apps/admin-web/src/main.ts` (updated)
|
|
- `apps/admin-web/src/App.vue` (updated)
|
|
- `apps/admin-web/src/router/meta.d.ts` (updated)
|
|
- `apps/admin-web/src/router/index.ts` (updated)
|
|
- `apps/admin-web/src/lib/api.ts` (updated)
|
|
- `apps/admin-web/src/lib/display.ts` (updated)
|
|
- `apps/admin-web/src/components/PageHero.vue` (created)
|
|
- `apps/admin-web/src/components/ArticleDetailDrawer.vue` (created)
|
|
- `apps/admin-web/src/components/TemplateGenerationDrawer.vue` (created)
|
|
- `apps/admin-web/src/views/LoginView.vue` (updated)
|
|
- `apps/admin-web/src/views/WorkspaceView.vue` (updated)
|
|
- `apps/admin-web/src/views/TemplatesView.vue` (created)
|
|
- `apps/admin-web/src/views/BrandsView.vue` (created)
|
|
- `apps/admin-web/src/views/FeatureStubView.vue` (updated)
|
|
- `apps/admin-web/src/layouts/AppShell.vue` (updated)
|
|
- `packages/shared-types/src/index.ts` (updated)
|
|
- `apps/admin-web/src/styles.css` (pending next cleanup pass)
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 6: Frontend Scope Recovery
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Read the planning files, Claude-side plan artifact, and architecture documents to recover the interrupted task context.
|
|
- Confirmed the backend chain is complete locally and the repository still has no `apps/` or `packages/` directories.
|
|
- Locked the next useful slice to a tenant-facing `admin-web` foundation rather than platform-side frontend work.
|
|
- Files created/modified:
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 7: Frontend Foundation
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Created the root pnpm workspace, root package scripts, and frontend-oriented `.gitignore`.
|
|
- Added shared frontend packages for TS config, API types, and an Axios-based client with auth refresh handling.
|
|
- Scaffolded `apps/admin-web` with Vite 8, Vue 3, TypeScript, Ant Design Vue, Pinia, Vue Router, and Vue Query.
|
|
- Files created/modified:
|
|
- `.gitignore` (created)
|
|
- `package.json` (created)
|
|
- `pnpm-workspace.yaml` (created)
|
|
- `packages/tsconfig/base.json` (created)
|
|
- `packages/shared-types/package.json` (created)
|
|
- `packages/shared-types/src/index.ts` (created)
|
|
- `packages/http-client/package.json` (created)
|
|
- `packages/http-client/src/index.ts` (created)
|
|
- `apps/admin-web/package.json` (created)
|
|
- `apps/admin-web/.env.example` (created)
|
|
- `apps/admin-web/index.html` (created)
|
|
- `apps/admin-web/tsconfig.json` (created)
|
|
- `apps/admin-web/vite.config.ts` (created)
|
|
|
|
### Phase 8: Admin-Web Initial Features
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Implemented the app bootstrap, Ant Design locale wiring, session persistence helpers, and auth store.
|
|
- Implemented the login page with seeded local credentials and redirect-aware sign-in flow.
|
|
- Implemented the protected shell layout, navigation, quota teaser, workspace dashboard, and placeholder routes for the rest of the information architecture.
|
|
- Files created/modified:
|
|
- `apps/admin-web/src/App.vue` (created)
|
|
- `apps/admin-web/src/main.ts` (created)
|
|
- `apps/admin-web/src/styles.css` (created)
|
|
- `apps/admin-web/src/lib/session.ts` (created)
|
|
- `apps/admin-web/src/lib/errors.ts` (created)
|
|
- `apps/admin-web/src/lib/api.ts` (created)
|
|
- `apps/admin-web/src/stores/pinia.ts` (created)
|
|
- `apps/admin-web/src/stores/auth.ts` (created)
|
|
- `apps/admin-web/src/router/meta.d.ts` (created)
|
|
- `apps/admin-web/src/router/index.ts` (created)
|
|
- `apps/admin-web/src/layouts/AppShell.vue` (created)
|
|
- `apps/admin-web/src/views/LoginView.vue` (created)
|
|
- `apps/admin-web/src/views/WorkspaceView.vue` (created)
|
|
- `apps/admin-web/src/views/FeatureStubView.vue` (created)
|
|
|
|
### Phase 9: Frontend Verification & Delivery
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Ran `pnpm install` for the new workspace and generated `pnpm-lock.yaml`.
|
|
- Fixed the initial frontend build errors related to Node typings and typed Axios wrapper method parameters.
|
|
- Switched Ant Design Vue registration from full-plugin mode to per-component registration to reduce the main bundle size.
|
|
- Ran `pnpm build:admin` successfully and confirmed production assets were emitted.
|
|
- Ran `pnpm --filter admin-web preview --host 127.0.0.1 --port 4173` and verified `/login` returned `HTTP/1.1 200 OK` with built asset references.
|
|
- Attempted browser automation verification, then fell back to HTTP verification after the local Playwright MCP environment failed on `/.playwright-mcp`.
|
|
- After Playwright became usable again, started the Vite dev server plus `tenant-api`, discovered the login CTA was not submitting on click, fixed the handler binding, and re-ran browser verification successfully with Playwright CLI.
|
|
- Files created/modified:
|
|
- `apps/admin-web/package.json` (updated)
|
|
- `apps/admin-web/tsconfig.json` (updated)
|
|
- `apps/admin-web/vite.config.ts` (updated)
|
|
- `apps/admin-web/src/main.ts` (updated)
|
|
- `apps/admin-web/src/views/LoginView.vue` (updated)
|
|
- `packages/http-client/src/index.ts` (updated)
|
|
- `pnpm-lock.yaml` (created)
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 1: Progress Verification
|
|
- **Status:** complete
|
|
- **Started:** 2026-03-31
|
|
- Actions taken:
|
|
- Read the task-specific design document.
|
|
- Inspected top-level repository layout and backend directory tree.
|
|
- Read the planning-with-files skill instructions and initialized planning files.
|
|
- Inspected `server/Makefile`, `server/cmd/tenant-api/main.go`, and `server/internal/bootstrap/bootstrap.go`.
|
|
- Verified there are 19 migration files and inspected `cmd/dev-seed/main.go`.
|
|
- Inspected `sqlc.yaml`, repository directory contents, and current repository integration test placeholders.
|
|
- Inspected auth/workspace/template/article/brand services and route registration to compare actual implementation with the design doc.
|
|
- Files created/modified:
|
|
- `task_plan.md` (created)
|
|
- `findings.md` (created)
|
|
- `progress.md` (created)
|
|
|
|
### Phase 2: Gap Analysis and Scope Lock
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Compared the repository contents against the design doc's expected `sqlc` and repository layout.
|
|
- Confirmed Step 4 is the earliest incomplete milestone because the generated code directory and repository wrappers are missing.
|
|
- Ran `make sqlc-generate` and observed a failing schema path in `sqlc.yaml`.
|
|
- Files created/modified:
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 3: Implementation
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Fixed `server/internal/tenant/repository/sqlc.yaml` and regenerated `sqlc` output under `server/internal/tenant/repository/generated/`.
|
|
- Added repository wrappers for auth, workspace, template, article, quota, and audit queries.
|
|
- Refactored auth/workspace/template services and handlers to use the new repository layer.
|
|
- Reworked template generation flow to use repository-backed transactional operations.
|
|
- Implemented atomic refresh token rotation in Redis and added `session_store` tests.
|
|
- Cleaned existing lint violations that were blocking local verification.
|
|
- Files created/modified:
|
|
- `server/internal/tenant/repository/sqlc.yaml` (updated)
|
|
- `server/internal/tenant/repository/generated/*` (generated)
|
|
- `server/internal/tenant/repository/common.go` (created)
|
|
- `server/internal/tenant/repository/auth_repo.go` (created)
|
|
- `server/internal/tenant/repository/workspace_repo.go` (created)
|
|
- `server/internal/tenant/repository/template_repo.go` (created)
|
|
- `server/internal/tenant/repository/article_repo.go` (created)
|
|
- `server/internal/tenant/repository/quota_repo.go` (created)
|
|
- `server/internal/tenant/repository/audit_repo.go` (created)
|
|
- `server/internal/tenant/app/auth_service.go` (updated)
|
|
- `server/internal/tenant/app/workspace_service.go` (updated)
|
|
- `server/internal/tenant/app/template_service.go` (updated)
|
|
- `server/internal/shared/auth/session_store.go` (updated)
|
|
- `server/internal/shared/auth/session_store_test.go` (created)
|
|
- `server/internal/tenant/transport/auth_handler.go` (updated)
|
|
- `server/internal/tenant/transport/workspace_handler.go` (updated)
|
|
- `server/internal/tenant/transport/template_handler.go` (updated)
|
|
|
|
### Phase 4: Testing & Verification
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Re-ran `make sqlc-generate` after the final code state and confirmed generation succeeds.
|
|
- Ran `go test ./...`, then `make test`, and confirmed all tests pass.
|
|
- Ran `make lint`, fixed the reported warnings, and re-ran until it passed cleanly.
|
|
- Verified the tenant-scope guard script exists and checked for CI workflow files.
|
|
- Files created/modified:
|
|
- `server/internal/tenant/repository/tx.go` (updated)
|
|
- `server/cmd/dev-seed/main.go` (updated)
|
|
- `server/internal/shared/auth/middleware_test.go` (updated)
|
|
- `server/internal/tenant/app/article_service.go` (updated)
|
|
- `server/internal/tenant/app/brand_service.go` (updated)
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
### Phase 5: Delivery
|
|
- **Status:** complete
|
|
- Actions taken:
|
|
- Added backend CI workflow under `.github/workflows/`.
|
|
- Added `tenant-scope-guard` to the backend `Makefile` so CI and local verification use the same entrypoint.
|
|
- Re-ran `make tenant-scope-guard`, `make test`, and `make lint` after the CI-related edits.
|
|
- Updated the backend `Makefile` to run `golang-migrate` through `go run -tags postgres` instead of requiring a preinstalled `migrate` binary.
|
|
- Ran `make dev-init` successfully, including Docker startup, migrations, and seed data.
|
|
- Started `tenant-api` and verified health endpoints plus auth login/me/refresh/logout behavior with positive and negative checks.
|
|
- Files created/modified:
|
|
- `.github/workflows/backend-ci.yml` (created)
|
|
- `server/Makefile` (updated)
|
|
- `task_plan.md` (updated)
|
|
- `findings.md` (updated)
|
|
- `progress.md` (updated)
|
|
|
|
## Test Results
|
|
| Test | Input | Expected | Actual | Status |
|
|
|------|-------|----------|--------|--------|
|
|
| Repository inspection | `ls`, `rg --files`, `sed` | Establish current backend coverage | Backend skeleton, migrations, services, and transport files exist | pass |
|
|
| Migration count | `find server/migrations -name '*.up.sql' | wc -l` | 19 schema migrations | 19 | pass |
|
|
| SQLC generation | `make sqlc-generate` | Generate typed code | Passed after fixing `sqlc.yaml` schema path | pass |
|
|
| Go tests | `go test ./...` | All packages compile and tests pass | Passed | pass |
|
|
| Make tests | `make test` | Roadmap acceptance command passes | Passed | pass |
|
|
| Lint | `make lint` | Roadmap acceptance command passes | Passed after fixing errcheck/ineffassign warnings | pass |
|
|
| CI workflow presence | `find . -path '*/.github/workflows/*' -type f` | At least one CI workflow if Step 9 is complete | `.github/workflows/backend-ci.yml` exists | pass |
|
|
| Tenant scope guard | `make tenant-scope-guard` | Tenant SQL filter guard passes | Passed | pass |
|
|
| Dev init | `make dev-init` | Infra, migrations, and seed complete successfully | Passed after fixing Makefile-managed migrate driver tags | pass |
|
|
| Live health | `GET /api/health/live` | HTTP 200 with alive status | Returned `code=0`, `status=alive` | pass |
|
|
| Ready health | `GET /api/health/ready` | HTTP 200 with ready status | Returned `code=0`, `status=ready` | pass |
|
|
| Login | `POST /api/auth/login` with `admin@geo.local / Admin@123` | Receive access/refresh tokens and user info | Passed | pass |
|
|
| Me | `GET /api/auth/me` with fresh access token | Current user payload returned | Passed | pass |
|
|
| Refresh | `POST /api/auth/refresh` with original refresh token | Receive rotated access/refresh token pair | Passed | pass |
|
|
| Logout revoke | `POST /api/auth/logout`, then `GET /api/auth/me` with old access token | Old access token rejected | Returned `40103 token_revoked` | pass |
|
|
| Refresh rotate invalidate | Reuse old refresh token after refresh | Old refresh token rejected | Returned `40121 refresh_session_expired` | pass |
|
|
| Workspace overview | `GET /api/tenant/workspace/overview` | Aggregated stats return successfully | Returned `code=0`, article/brand counts present | pass |
|
|
| Workspace recent articles | `GET /api/tenant/workspace/recent-articles` | Recent list returns successfully | Returned `code=0` | pass |
|
|
| Workspace quota summary | `GET /api/tenant/workspace/quota-summary` | Quota summary returns successfully | Returned `code=0`, balance/total present | pass |
|
|
| Workspace template cards | `GET /api/tenant/workspace/template-cards` | Template cards return successfully | Returned `code=0`, count=4 | pass |
|
|
| Template generate flow | `POST /api/tenant/templates/{id}/generate` + article detail/version checks | Article generation completes end-to-end | Article `1` completed, versions count `1`, quota `100 -> 99` | pass |
|
|
| Brand soft delete and recreate | Create brand, delete, recreate same name | Recreate succeeds after soft delete | Original brand `1` deleted, recreated as brand `2` | pass |
|
|
| Question version history | Create question, update, list versions | Version history retained | Returned 2 versions, latest text updated | pass |
|
|
| Competitor CRUD basic flow | Create competitor then list | Competitor visible under brand | Returned count `1` | pass |
|
|
| Frontend workspace install | `pnpm install` | Workspace dependencies install cleanly | Passed | pass |
|
|
| Frontend build | `pnpm build:admin` | `admin-web` compiles and emits production assets | Passed | pass |
|
|
| Frontend preview login HTML | `curl -I http://127.0.0.1:4173/login` | Preview route returns `200 OK` | Returned `HTTP/1.1 200 OK` | pass |
|
|
| Frontend preview asset shell | `curl -s http://127.0.0.1:4173/login` | HTML references built CSS/JS assets | Returned built asset tags for `index-CtRpygQP.js` and `index-DFz5-Rsr.css` | pass |
|
|
| Frontend browser login flow | `pnpm dlx @playwright/test test .tmp-playwright/admin-web.spec.js --reporter=line` | Login succeeds and workspace renders | Passed after binding the login CTA directly to `handleSubmit` | pass |
|
|
|
|
## Error Log
|
|
| Timestamp | Error | Attempt | Resolution |
|
|
|-----------|-------|---------|------------|
|
|
| 2026-03-31 | None yet | 1 | N/A |
|
|
| 2026-03-31 | `make sqlc-generate` failed due to invalid schema path in `sqlc.yaml` | 1 | Fixed by changing schema path to `../../../migrations/` |
|
|
| 2026-03-31 | `make lint` failed on several existing warnings | 1 | Fixed all reported warnings and re-ran lint successfully |
|
|
| 2026-03-31 | `make dev-init` failed because go-run migrate lacked the postgres driver tag | 1 | Updated `MIGRATE_CMD` to `go run -tags postgres ...` and reran successfully |
|
|
| 2026-03-31 | Gemini CLI returned `429 MODEL_CAPACITY_EXHAUSTED` on `gemini-3.1-pro-preview` | 1 | Stopped pursuing Gemini once the user said not to use Gemini |
|
|
| 2026-03-31 | Initial frontend build failed on missing Node typings and implicit `any` parameters | 1 | Removed the Node type dependency from app TS config, simplified the Vite config, and typed the API client methods explicitly |
|
|
| 2026-03-31 | Playwright MCP browser open failed on `/.playwright-mcp` | 1 | Used preview HTTP verification instead of blocking on browser environment setup |
|
|
| 2026-03-31 | Browser click on the login CTA did not submit the form, so Playwright stayed on `/login` | 1 | Added an explicit `@click=\"handleSubmit\"` binding to the CTA and re-ran the E2E flow successfully |
|
|
|
|
## 5-Question Reboot Check
|
|
| Question | Answer |
|
|
|----------|--------|
|
|
| Where am I? | Phase 9 complete |
|
|
| Where am I going? | Next useful slice is turning the placeholder routes into real pages, starting with template creation and brand management |
|
|
| What's the goal? | Resume the interrupted task by adding the missing `admin-web` frontend foundation on top of the finished backend |
|
|
| What have I learned? | The tenant backend is stable enough to support a real login + dashboard frontend slice, and a real browser pass was valuable because it caught a submit wiring bug that static checks missed |
|
|
| What have I done? | Added the pnpm frontend workspace, built `apps/admin-web`, wired auth and dashboard data to `tenant-api`, reduced the bundle size, and passed install/build/preview plus browser login verification |
|