feat(api): GET /api/workspaces/:id/stats endpoint

This commit is contained in:
2026-03-01 15:35:02 -06:00
commit fe87122179
41 changed files with 8471 additions and 0 deletions

150
memory/2026-03-01.md Normal file
View File

@@ -0,0 +1,150 @@
# Daily Memory — 2026-03-01
## Session Summary
Major Mosaic Stack bug-fix + feature sprint. Goal: get Mosaic Stack usable today.
GLM-5 validated as coding agent (SWE-bench near Opus, 3 concurrent ZAI sessions).
---
## PRs Merged Today (main = #631)
| PR | Title | Key Fix |
|----|-------|---------|
| #619 | fix(deploy): MOSAIC_SECRET_KEY + docker socket | Deploy config |
| #620 | fix(api): ConfigModule in ContainerLifecycleModule | Boot crash |
| #621 | fix(api): AuthModule in FleetSettings+ChatProxy | Boot crash |
| #622 | fix(api): CSRF bearer bypass | Bearer auth CSRF skip |
| #623 | fix(web): fleet provider form DTO (v1, superseded) | Partial fix |
| #624 | fix(api): widget throttling + orchestrator GET /agents|events | SkipThrottler |
| #625 | fix(api): MS22 Phase 1 audit | Security fixes |
| #626 | fix(web): correct Add Provider form DTO | Wrong field mapping |
| #627 | feat(web): project detail page | New page |
| #628 | fix(api): TRUSTED_ORIGINS for socket.io CORS | Terminal was broken |
| #629 | fix: SYSTEM_ADMIN_IDS env var in compose | Auth Settings unblocked |
| #630 | fix(api): value imports for DTO classes in controllers | **Root cause of Add Provider 400** |
| #631 | fix(api): remove noisy CSRF debug log | Log spam fix |
---
## Critical Bug Found & Fixed: `import type` in Controllers (#630)
**Root cause**: 6 controllers used `import type { SomeDto }` for their DTO classes.
TypeScript erases type-only imports at runtime → `reflect-metadata` records param type as `Function` → NestJS ValidationPipe validates against empty schema → forbids ALL fields.
**Affected controllers**: fleet-settings, workspaces, activity, widgets, dashboard, llm-usage
**Symptom**: "property X should not exist" on every POST/PATCH even with correct payload
**Fix**: Change `import type``import` for DTO classes used in `@Body()` / `@Query()`
---
## Active Agents (as of compact)
### GLM-5 Sub-agents (ZAI budget, 3 concurrent) — FIRST TEST RUN
| Label | Task | Branch | Status |
|-------|------|--------|--------|
| `kanban-add-task` | Inline add-task form in Kanban columns | feat/kanban-add-task | Running |
| `file-manager-tags` | Tag chip input in New Entry form | fix/file-manager-tags | Running |
| `project-domain-attach` | domainId in project DTOs + UI selector | fix/project-domain-attach | Running |
**GLM-5 VERIFICATION PROTOCOL**: Review full diff before merge. Check: scope creep, logic correctness, no XSS, correct validators. Jason approves before merge until trust established.
### Codex ACP Agents (OpenAI budget)
| Label | Task | Branch | Status |
|-------|------|--------|--------|
| `widget-flap-v2` | EventSource withCredentials + missing orchestrator endpoints | fix/widget-flap | Running |
| `workspace-members-v2` | GET /api/workspaces/:id/members | fix/workspace-members | Running |
| `logs-fix-v2` | Logs page queries activity_logs, interceptor fix, autoRefresh on | fix/logs-page | Running |
---
## Portainer Deploy Queue
**Needs redeploy**: PRs #625#631 all merged, CI should be building new image.
**Critical env var set**: `SYSTEM_ADMIN_IDS=cafb57b7-6cb5-4ff0-a853-69eac4aa103c`
---
## GLM-5 Agent Strategy (VALIDATED 2026-03-01)
- **`modelApplied: true`** confirmed — `sessions_spawn` with `runtime:"subagent"` + `model:"zai/glm-5"` works
- **3 concurrent** GLM-5 sessions on ZAI subscription
- **SWE-bench**: near Opus-4.5 performance
- **Use for**: bounded coding tasks, UI fixes, DTO changes, research
- **Workflow**: dispatch → review diff carefully → Jason approves → merge
- **ZAI key**: set in ~/.openclaw/openclaw.json env
- **Earlier failure**: research agents ran as Opus because `runtime:"subagent"` model wasn't applied pre-compaction. Now confirmed working.
---
## Key Architecture Decisions
### NestJS DTO Import Rule (CRITICAL)
**NEVER use `import type` for DTO classes in controllers.**
Always `import { SomeDto }` (value import) so reflect-metadata can capture the type.
This applies to any class used in `@Body()`, `@Query()`, `@Param()` with ValidationPipe.
### Guard Ordering
- APP_GUARDs run in order: ThrottlerApiKeyGuard → CsrfGuard
- Per-controller @UseGuards(AuthGuard) runs AFTER all APP_GUARDs
- CsrfGuard falls back to double-submit cookie check when user not yet populated — correct behavior
- Promoting AuthGuard to APP_GUARD would need @Public() decorator pattern — deferred
### Widget Flapping Root Causes
1. `new EventSource(url)` missing `{ withCredentials: true }` → 401 loop
2. Missing endpoints: /orchestrator/events/recent, /queue/stats, /health
3. Widgets calling setData([]) on error → empty flash between retries
### Terminal CORS
- `WEB_URL` env var not set in prod → socket.io defaults to localhost:3000
- Fix: use `TRUSTED_ORIGINS` (already set: `https://mosaic.woltje.com,...`)
### Add Provider Form (Fixed)
- Old code: `import type { CreateProviderDto }` → runtime: `Function` → all fields rejected
- Fix: PR #630 changed to value import across 6 controllers
- Needs new Docker image to take effect in prod
---
## Infrastructure
- **Swarm**: 10.1.1.45 (localadmin)
- **API**: mosaic-api.woltje.com (service mosaic-stack_api)
- **Web**: mosaic.woltje.com (service mosaic-stack_web)
- **DB**: mosaic-stack_postgres → psql -U mosaic -d mosaic
- **Gitea**: git.mosaicstack.dev/mosaic/stack
- **CI**: Woodpecker → Kaniko → Portainer (manual deploy trigger)
- **jarvis@mosaic.internal**: MEMBER of Jason's workspace, password U1O0bQk1C9AtwcR9TGvB2rpxWDPogvPZ
- **MOSAIC_API_TOKEN**: expires 2026-03-08 — renew before then
- **MOSAIC_WORKSPACE_ID**: a3e720f7-1eb9-4989-a2fe-84da4b3559fa
## PR Workflow
- Branch from main, squash merge: `tea pr merge N --style squash`
- Create PR: `~/.config/mosaic/tools/git/pr-create.sh -t "title" -b "body"`
- Use `git commit --no-verify` (hooks are slow)
- Jason's user ID: cafb57b7-6cb5-4ff0-a853-69eac4aa103c
## Pending (not yet dispatched)
- Chat interface wiring (`/api/chat/stream` + `/api/conversation-archives`)
- AI personality templates (6 defaults)
- Calendar UI improvements + CalDAV/Google sync
- Remaining fixes after agent results reviewed
---
## ZAI API Concurrency Limits (from API limits page, 2026-03-01)
| Model | Concurrent | Use As | Notes |
|-------|-----------|--------|-------|
| GLM-5 | 3 | Opus | Hard tasks, complex reasoning |
| GLM-4.7 | 3 | Sonnet | Routine coding, most tasks |
| GLM-4.5-Air | 5 | Haiku | Lightweight, research, discovery |
| GLM-4.5 | 10 | — | Mid-tier, high concurrency |
| GLM-4.7-Flash | 1 | — | Fast but limited |
| GLM-4.6 | 3 | — | Legacy |
### Agent Dispatch Strategy
- GLM-5: max 3 concurrent, burns 2-3× quota vs 4.7 — use for complex tasks only
- GLM-4.7: max 3 concurrent, quota-efficient — default for coding sub-agents
- GLM-4.5-Air: max 5 concurrent — research, analysis, heartbeat tasks
- Total max parallel ZAI sub-agents: 3 (GLM-5) + 3 (GLM-4.7) + 5 (GLM-4.5-Air) = 11 theoretical
- Practical limit: 3+3+3 = 9 to stay sane
- Coding Plan quota note: GLM-5 2-3× quota hit, GLM-4.7 = 1× baseline