H0-01: Reject Apple login mock fallback in production
H0-02: Protect /internal/* with InternalAuthGuard (X-Internal-API-Key)
H0-03: JwtAuthGuard check user status (deletedAt, status)
H0-04: Refresh token check user status + revoke all on deleted
H0-05: User/admin JWT isolation (type=user/admin, enforce ADMIN_JWT_ACCESS_SECRET)
H0-06: Add DTOs for import/source/learning-session controllers
H0-07: 22 E2E tests (h0.e2e-spec.ts), 5 iOS integration docs
Tests: 47/47 (H0 22 + M0 25), no regression.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
UploadedFile.sizeBytes is BigInt → JSON.stringify throws TypeError.
Add BigInt.prototype.toJSON to convert to Number globally.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
prisma migrate deploy requires pre-generated migration files which won't
exist when schema is edited directly. db push syncs schema directly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- GiteaService: use /repos/search?q= with fallback to /user/repos, remove slow per-repo API calls
- Frontend: add RepoSelector dropdown to Issues/Milestones/Releases tabs
- Fix Gitea panel tab (was filtered out by conditional undefined)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Affected: Notification, AiUsageLog, LearningSession, AiAnalysisResult,
DocumentImport, ReviewLog, ChatSession, ChatMessage
- All admin list queries use ORDER BY createdAt DESC — without indexes
these required full table scans on large tables
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Only fetch display-needed columns, skip backText TEXT column
- Reduces data transfer and query time significantly
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The admin review list query uses ORDER BY createdAt DESC but there was no
index on createdAt, causing full table scan + filesort on large tables.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add scope field to Notification model (user/admin)
- AdminNotificationsController: list, send, mark read
- Generate endpoints: cost-alert, import-failure, key-expiring
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add AgentTask and AgentArtifact Prisma models
- HermesAgentController: list tasks, approve/reject, list artifacts
- AAPI: GET /admin-api/hermes/tasks, POST approve/reject, GET /admin-api/hermes/artifacts
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add CleanupJob Prisma model
- Create BackupService with backup/cleanup job tracking
- Create BackupController (AAPI: GET jobs, POST trigger backup, GET cleanup, POST cleanup)
- Supports cleanup types: soft-delete, api-metrics, task-logs
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add ServiceHealth Prisma model for health check records
- Add getHealthChecks() with local + remote service checks
- Add GET /admin-api/servers/health endpoint
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add AdminLearningController with 3 endpoints:
GET /admin-api/learning/sessions — learning sessions list
GET /admin-api/learning/analysis — AI analysis results
GET /admin-api/learning/ai-usage — AI usage logs
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- import-candidate: explicit any[] type for safeCandidates
- growth: date→activityDate (actual DailyLearningActivity field name)
- review: Number(rating) for SM-2 math, remove easeFactor from updateCard call
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- GrowthService: streak calculation from DailyLearningActivity
- Recommendations: focus items, due review cards, new knowledge items
- New API: GET /api/activity/streak, GET /api/activity/recommendations
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Publish AIAnalysisCompleted domain event after each AI analysis
- Auto-generate FocusItems from AI-identified weaknesses
- Review Engine subscribes to AIAnalysisCompleted to create ReviewCards
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- SystemKnowledgeBaseSeed: auto-creates built-in 新手引导知识库
- Content Safety check on candidate accept() and createCandidates()
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Same issue as KnowledgeBaseService — NestJS can't resolve
ContentSafetyService in RagChatModule without @Optional().
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Artifact base model for future FlashcardSet/Quiz/StudyGuide
- KnowledgeItem.learnable boolean (default true) for M3 LearningSession
- Admin AAPI: GET candidates (by status/kbId), GET items (by kbId)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ImportStepLog model for tracking each import pipeline step
- Admin AAPI: import list, detail with step logs, retry failed
- Admin page: ImportMonitor with drawer detail view
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Direct app verified healthy — code works. CI script bugs fixed:
- kill/wait of background process returns 143 (SIGTERM), now ignored
- systemd start failure is non-fatal since direct run validated
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>