# Project State Summary ## Implementation Summary ### 1. Project structure overview (apps / libs / packages actually present) - apps: `apps/box-app-api`, `apps/box-mgnt-api`, `apps/box-stats-api` - libs: `libs/common`, `libs/core`, `libs/db` - packages: none present - data/infra: `prisma/mysql`, `prisma/mongo`, `prisma/mongo-stats` - docs/artifacts: `docs`, `dist`, `logs`, `build.log`, `structures.txt` ### 2. Implemented backend applications (what can actually boot/run) - box-mgnt-api: Fastify-based NestJS app (`apps/box-mgnt-api/src/main.ts`) - box-app-api: Express-based NestJS app (`apps/box-app-api/src/main.ts`) - box-stats-api: Express-based NestJS app (`apps/box-stats-api/src/main.ts`) ### 3. Implemented modules per app (auth, user, config, etc.) - box-mgnt-api - Core + auth: Auth, User, Role, Menu, LoginLog, OperationLog, QuotaLog - Feature: Ads, Category, Channel, Tag, VideoMedia, SystemParams, SyncVideomedia, ProviderVideoSync, S3, Health, ImageUpload, MgntHttpService - Cache: CacheSyncModule, CoreModule (cache warmups/builders), RedisModule - Cross-cutting: CommonModule (global interceptors/filters/logging), SharedModule (Prisma, HttpModule) - Dev-only: DevVideoCacheModule (loaded only when `NODE_ENV !== 'production'`) - UNUSED: OssModule exists in `apps/box-mgnt-api/src/mgnt-backend/feature/oss/oss.module.ts` but is commented out in `apps/box-mgnt-api/src/mgnt-backend/feature/feature.module.ts` - box-app-api - Auth, Ads, Video, Recommendation, Homepage, SysParams, Stats, Health - Infrastructure: PrismaMongoModule (Mongo + MongoStats Prisma services), RedisModule, RedisCacheModule (cache-manager), RabbitmqModule - box-stats-api - UserLoginModule, RabbitmqConsumerModule, StatsEventsModule, PrismaMongoModule, RedisModule ### 4. Implemented infrastructure - database(s): MySQL (`prisma/mysql`), MongoDB (`prisma/mongo`), MongoDB stats (`prisma/mongo-stats`) - ORM/ODM: Prisma (`@prisma/client`), services in `libs/db/src/prisma/*` - cache: Redis via `ioredis` (`libs/db/src/redis/*`), cache-manager via `cache-manager-ioredis-yet` in `apps/box-app-api/src/redis/redis-cache.module.ts` - message queue: RabbitMQ via `amqplib` (`apps/box-app-api/src/rabbitmq/*`, `apps/box-stats-api/src/feature/rabbitmq/*`) ### 5. Implemented cross-cutting concerns - auth / guards - box-mgnt-api: global JWT + RBAC guards (`apps/box-mgnt-api/src/mgnt-backend/core/auth/auth.module.ts`), LocalAuthGuard for login, RateLimitGuard on auth endpoints, MFA flow in auth service/guards - box-app-api: JwtAuthGuard used on specific endpoints (ads click/impression, stats events, video click, rabbitmq fallback) - UNUSED: `MfaGuard` exists only in `libs/common/src/guards/mfa.guard.ts` with no references - exception filters - HttpExceptionFilter applied globally via `libs/common/src/common.module.ts` and `apps/box-app-api/src/app.module.ts` - UNUSED: `AllExceptionsFilter` exists only in `libs/common/src/filters/all-exceptions.filter.ts` - logging - box-mgnt-api: `nestjs-pino` + Correlation/Logging/OperationLog/Response interceptors in `libs/common/src/common.module.ts` - box-app-api / box-stats-api: Nest Logger in `main.ts` - config loading - box-mgnt-api: `ConfigModule` with env validation (`apps/box-mgnt-api/src/config/env.validation.ts`) - box-app-api: `ConfigModule` with `.env.app` + `.env` - box-stats-api: `ConfigModule` with `.env.stats` + `.env` ### 6. Implemented APIs/endpoints (high-level, no payload details) - box-app-api (global prefix `/api/v1`) - Auth: `/auth/login` - Ads: `/ads/list`, `/ads/click`, `/ads/impression` - Video: `/video/recommended`, `/video/category/:channelId/:categoryId/latest`, `/video/categories-with-tags`, `/video/list`, `/video/search-by-tag`, `/video/click` - Recommendation (public): `/recommend/video/:videoId`, `/recommend/ad/:adId` - Recommendation (internal-style): `/api/v1/recommendation/videos/:videoId/similar`, `/api/v1/recommendation/ads/:adId/similar`, `/api/v1/recommendation/ads/:adId/similar-simple` - Homepage: `/homepage` - Sys params: `/sys-params/ad-types` - Stats events: `/stats/ad/click`, `/stats/video/click`, `/stats/ad/impression` - Health: `/health` - RabbitMQ: `/rabbitmq/fallback/replay`, `/rabbitmq/fallback/status`, `/rabbitmq/fallback/queue-size`, `/api/v1/internal/rabbitmq/status` - box-stats-api (global prefix `/api/v1`) - Internal stats: `/internal/stats/ingestion`, `/internal/stats/aggregate/ads`, `/internal/stats/aggregate/videos` - Debug: `/internal/stats/debug/redis/videos/top`, `/internal/stats/debug/redis/ads/top` - box-mgnt-api (global prefix `/api/v1`, routed under `/mgnt`) - Auth: `/api/v1/mgnt/auth/login`, `/login2fa`, `/logout`, `/2fa/generate`, `/2fa/setup`, `/2fa/enable`, `/permission`, `/abilities` - Users: `/api/v1/mgnt/users` (CRUD + list/search), `/me`, `/me/password`, `/me/personal-info`, `/role/:roleId`, `/admin-remove-2fa`, `/admin-set-2fa`, `/reset-password` - Roles: `/api/v1/mgnt/roles` (list/create/update/delete/permissions) - Menus: `/api/v1/mgnt/menus` (list/tree/create/update/delete) - Logs: `/api/v1/mgnt/login-logs`, `/operation-logs`, `/quota-logs` - System params: `/api/v1/mgnt/system-param` (list/create/update/get) - Ads: `/api/v1/mgnt/ads` (list/get/create/update/delete), `/ads/:id/cover`, `/ads/modules/list` - Ads legacy images: `/api/v1/mgnt/ads-legacy/*` - Categories: `/api/v1/mgnt/categories` - Channels: `/api/v1/mgnt/channels` - Tags: `/api/v1/mgnt/tags` - Video media: `/api/v1/mgnt/video-media` (list/create/update/status/sync/etc.) - Sync: `/api/v1/mgnt/sync-videomedia`, `/api/v1/mgnt/provider-video-sync` - S3 utilities: `/api/v1/mgnt/s3/*` (policy, signed URL/image/video helpers) - Health: `/api/v1/mgnt/health/redis` - Cache sync/admin: `/api/v1/mgnt/cache/*`, `/mgnt-debug/cache-sync/*`, `/api/v1/mgnt/admin/cache/video/*` - Dev-only (non-prod): `/api/v1/mgnt/dev/cache/*`, `/api/v1/mgnt/dev/video/*` ### 7. Implemented build / dev / deploy scripts - Dev: `dev:mgnt`, `dev:app`, `dev:stats` - Build: `build:mgnt`, `build:app`, `build:stats` - Start: `start:mgnt`, `start:app`, `start:stats` - Prisma: generate/migrate/seed/setup for MySQL and Mongo - Tooling: `typecheck`, `typecheck:watch`, `lint`, `lint:fix` ### 8. Known constraints enforced in code - Global API prefixing: `/api/v1` on all apps; management APIs additionally under `/mgnt` router - ValidationPipe with `whitelist` and `transform` enabled (all apps) - CORS configured by env (`APP_CORS_ORIGIN`) with defaults and method restrictions - File upload size limit 30MB for mgnt Fastify multipart - Internal endpoints guarded by environment checks (RabbitMQ status) and dev-only module gating by `NODE_ENV` - Auth enforcement: mgnt uses global JWT + RBAC guards; login endpoints rate-limited; app/stats use JwtAuthGuard on selected endpoints - BigInt JSON serialization override in mgnt main ### 9. Explicit TODOs or TODO comments found in code - `apps/box-stats-api/src/feature/stats-events/stats-aggregation.service.ts`: TODO for tag-based ad stats - `apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.controller.ts`: TODO for delete video media - `apps/box-mgnt-api/src/cache-sync/cache-sync.service.ts`: TODO for HOME/CHANNEL/TRENDING list rebuild - `libs/core/src/cache/video/list/video-list-cache.builder.ts`: multiple TODOs for refactor after schema change ### 10. Ambiguous or risky areas that require human confirmation - UNCLEAR – controller paths in `apps/box-app-api/src/feature/recommendation/recommendation.controller.ts` and `apps/box-app-api/src/rabbitmq/rabbitmq-status.controller.ts` hardcode `api/v1` while `apps/box-app-api/src/main.ts` also sets a global `api/v1` prefix; confirm whether routes are intended to be `/api/v1/api/v1/...` or just `/api/v1/...` - UNCLEAR – `GET /api/v1/video/recommended` reads `req.user` but has no guard; confirm if another auth middleware populates `req.user` or if this is intended to be public - UNCLEAR – `apps/box-stats-api/src/feature/stats-events/stats-internal.controller.ts` exposes internal/debug endpoints without auth; confirm expected protection model - UNUSED – commented endpoints (e.g., `apps/box-app-api/src/feature/sys-params/sys-params.controller.ts` constants, `apps/box-app-api/src/feature/ads/ad.controller.ts` ad URL, `apps/box-mgnt-api/src/mgnt-backend/core/auth/auth.controller.ts` OAuth routes) appear intentionally disabled; confirm whether they should stay disabled ## Feature Classification | Feature / Module | Status | Evidence in Code | Risk if Touched | |---|---|---|---| | box-mgnt-api app | PRODUCTION-READY | `apps/box-mgnt-api/src/main.ts`, `apps/box-mgnt-api/src/app.module.ts`, scripts `dev:mgnt/start:mgnt` in `package.json` | High: core admin backend | | Mgnt Core Auth (JWT/RBAC/2FA) | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/core/auth/auth.module.ts` is imported via `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | High: login + permissions | | Mgnt Users | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/core/user/user.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | High: admin user mgmt | | Mgnt Roles | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/core/role/role.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | High: RBAC | | Mgnt Menus | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/core/menu/menu.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium: admin UI navigation | | Mgnt Logs (login/operation/quota) | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/core/logging/*` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium: audit trails | | Mgnt Ads management | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/ads/ads.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | High: ad CRUD | | Mgnt Categories | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/category/category.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium: app taxonomy | | Mgnt Channels | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/channel/channel.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium | | Mgnt Tags | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/tag/tag.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium | | Mgnt Video Media | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | High: video catalog | | Mgnt System Params | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/system-params/system-params.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium | | Mgnt Sync Video Media | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/sync-videomedia/sync-videomedia.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium: sync logic | | Mgnt Provider Video Sync | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/provider-video-sync/provider-video-sync.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/feature/feature.module.ts` | Medium | | Mgnt S3 endpoints | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/s3/s3.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Medium: upload/signing | | Mgnt Health (Redis) | INTERNAL-ONLY | `apps/box-mgnt-api/src/mgnt-backend/feature/health/health.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts` | Low: monitoring | | Mgnt Cache Sync (admin/debug) | INTERNAL-ONLY | `apps/box-mgnt-api/src/cache-sync/cache-sync.module.ts` wired in `apps/box-mgnt-api/src/app.module.ts` | Medium: cache integrity | | Mgnt Dev Video Cache tools | INTERNAL-ONLY | `apps/box-mgnt-api/src/dev/dev-video-cache.module.ts` only imported when `NODE_ENV !== 'production'` in `apps/box-mgnt-api/src/app.module.ts` | Medium: dev diagnostics | | Mgnt ImageUpload service | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/image-upload/image-upload.module.ts` imported by feature services (ads/video-media) | Medium: media pipeline | | Mgnt MgntHttpService | PRODUCTION-READY | `apps/box-mgnt-api/src/mgnt-backend/feature/mgnt-http-service/mgnt-http-service.module.ts` wired in `apps/box-mgnt-api/src/mgnt-backend/feature/feature.module.ts` | Low | | Mgnt OSS module | DEAD / UNUSED | `apps/box-mgnt-api/src/mgnt-backend/feature/oss/oss.module.ts` not imported (commented in `apps/box-mgnt-api/src/mgnt-backend/feature/feature.module.ts`) | Low: unused | | box-app-api app | PRODUCTION-READY | `apps/box-app-api/src/main.ts`, `apps/box-app-api/src/app.module.ts`, scripts `dev:app/start:app` in `package.json` | High: public API | | App Auth (JWT) | PRODUCTION-READY | `apps/box-app-api/src/feature/auth/auth.module.ts` imported in `apps/box-app-api/src/app.module.ts` | High | | App Ads API | PRODUCTION-READY | `apps/box-app-api/src/feature/ads/ad.module.ts` imported in `apps/box-app-api/src/app.module.ts` | High | | App Video API | PRODUCTION-READY | `apps/box-app-api/src/feature/video/video.module.ts` imported in `apps/box-app-api/src/app.module.ts` | High | | App Homepage API | PRODUCTION-READY | `apps/box-app-api/src/feature/homepage/homepage.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Medium | | App Sys Params API | PRODUCTION-READY | `apps/box-app-api/src/feature/sys-params/sys-params.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Medium | | App Recommendation API (public) | PRODUCTION-READY | `apps/box-app-api/src/feature/recommendation/recommendation.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Medium | | App Stats Events publisher | PRODUCTION-READY | `apps/box-app-api/src/feature/stats/stats.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Medium | | App Health endpoint | INTERNAL-ONLY | `apps/box-app-api/src/health/health.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Low | | App RabbitMQ publisher + fallback | INTERNAL-ONLY | `apps/box-app-api/src/rabbitmq/rabbitmq.module.ts` imported in `apps/box-app-api/src/app.module.ts` | Medium: event pipeline | | App RabbitMQ status endpoint | INTERNAL-ONLY | env guard in `apps/box-app-api/src/rabbitmq/rabbitmq-status.controller.ts` | Low | | box-stats-api app | PRODUCTION-READY | `apps/box-stats-api/src/main.ts`, `apps/box-stats-api/src/app.module.ts`, scripts `dev:stats/start:stats` in `package.json` | High: stats processing | | Stats RabbitMQ consumer | PRODUCTION-READY | `apps/box-stats-api/src/feature/rabbitmq/rabbitmq-consumer.module.ts` imported in `apps/box-stats-api/src/app.module.ts` | Medium | | Stats aggregation scheduler | PRODUCTION-READY | `apps/box-stats-api/src/feature/stats-events/stats-events.module.ts` imported in `apps/box-stats-api/src/app.module.ts` | Medium | | Stats internal/debug endpoints | INTERNAL-ONLY | `apps/box-stats-api/src/feature/stats-events/stats-internal.controller.ts` | Low | | Shared Prisma services (MySQL/Mongo/MongoStats) | PRODUCTION-READY | `libs/db/src/prisma/prisma.module.ts` exported by `libs/db/src/shared.module.ts` used in mgnt/stats | High: data access | | Redis module/service | PRODUCTION-READY | `libs/db/src/redis/redis.module.ts` used in all apps | High: cache/messaging | | CommonModule interceptors/filters | PRODUCTION-READY | `libs/common/src/common.module.ts` imported in `apps/box-mgnt-api/src/app.module.ts` | Medium: response/logging | | AllExceptionsFilter | DEAD / UNUSED | `libs/common/src/filters/all-exceptions.filter.ts` no wiring found | Low | | MfaGuard | DEAD / UNUSED | `libs/common/src/guards/mfa.guard.ts` no usage | Low | ## How This Project Currently Runs ### 1) Start `box-mgnt-api` - Command(s): `pnpm dev:mgnt` (nest start), or `pnpm build:mgnt` then `pnpm start:mgnt` (`node dist/apps/box-mgnt-api/src/main.js`) - Env loading: `ConfigModule.forRoot` uses `.env.mgnt` then `.env` in `apps/box-mgnt-api/src/app.module.ts` - REQUIRED (validated): `MYSQL_URL`, `MONGO_URL`, `JWT_SECRET`, `REDIS_HOST`, `REDIS_PORT` - REQUIRED in practice: `MONGO_STATS_URL` (Prisma MongoStats connects on init; schema expects `env("MONGO_STATS_URL")`) - OPTIONAL (defaults/hardcoded): `APP_HOST`, `HOST`, `APP_PORT`/`PORT`, `APP_CORS_ORIGIN`, `REDIS_PASSWORD`, `REDIS_DB`, `REDIS_KEY_PREFIX`, `REDIS_TLS`, `JWT_EXPIRES_IN_SECONDS`, `ENCRYPTION_KEY` - External services contacted at runtime: MySQL (Prisma connect), MongoDB (Prisma connect), MongoStats (Prisma connect), Redis (ioredis client init). S3 only when S3 endpoints are used; `S3Service` relies on `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_S3_REGION_NAME`, `AWS_STORAGE_BUCKET_NAME`, optional `AWS_S3_ENDPOINT_URL` ### 2) Start `box-app-api` - Command(s): `pnpm dev:app` (uses `dotenv -e .env.app -- nest start ...`), or `pnpm build:app` then `pnpm start:app` (`node dist/apps/box-app-api/src/main.js`) - Env loading: `ConfigModule.forRoot` uses `.env.app` then `.env` in `apps/box-app-api/src/app.module.ts` (dev command also sets env) - REQUIRED: `MONGO_URL`, `MONGO_STATS_URL` (Prisma Mongo + MongoStats clients connect on init; schemas use `env("MONGO_URL")` and `env("MONGO_STATS_URL")`) - REQUIRED in practice: Redis connection parameters; defaults are used if unset (`REDIS_HOST` defaults to `127.0.0.1`, `REDIS_PORT` defaults to `6379`) - OPTIONAL (defaults/hardcoded): `APP_HOST`, `HOST`, `APP_PORT`/`PORT`, `APP_CORS_ORIGIN`, `IMAGE_ROOT_PATH` (default `/data/box-images`), `JWT_SECRET` (defaults to `default-secret-key`), `JWT_EXPIRES_IN` (defaults to `7d`) - RabbitMQ: `RABBITMQ_URL` is OPTIONAL; if missing, publisher logs and stays open-circuit - External services contacted at runtime: MongoDB, MongoStats, Redis (both RedisModule and cache-manager). RabbitMQ if `RABBITMQ_URL` is set. Filesystem for static images at `IMAGE_ROOT_PATH` via Express static middleware ### 3) Start `box-stats-api` - Command(s): `pnpm dev:stats` (uses `dotenv -e .env.stats -- nest start ...`), or `pnpm build:stats` then `pnpm start:stats` (`node dist/apps/box-stats-api/src/main.js`) - Env loading: `ConfigModule.forRoot` uses `.env.stats` then `.env` in `apps/box-stats-api/src/app.module.ts` - REQUIRED: `MONGO_STATS_URL` (Prisma MongoStats connects on init) - REQUIRED in practice: Redis connection parameters; defaults are used if unset (`REDIS_HOST` default `127.0.0.1`, `REDIS_PORT` default `6379`) - OPTIONAL (defaults/hardcoded): `APP_HOST`, `HOST`, `APP_PORT`/`PORT`, `APP_CORS_ORIGIN` - RabbitMQ: `RABBITMQ_URL` OPTIONAL; consumer logs error and returns without connecting if missing - External services contacted at runtime: MongoStats, Redis. RabbitMQ only if `RABBITMQ_URL` is set ### Hardcoded/default behaviors to note - `box-app-api` JWT secret defaults to `default-secret-key` and expiration defaults to `7d` if env is missing - All apps default to binding host `0.0.0.0` and ports `3300/3301/3302` if `APP_PORT`/`PORT` not set - `box-app-api` and `box-mgnt-api` serve static images from `/data/box-images` if `IMAGE_ROOT_PATH` is not set ## Plan vs Current Implementation ### 1. Features already implemented beyond the original plan - box-stats-api exists and runs with RabbitMQ consumer + aggregation + internal endpoints, while docs call it “future/upcoming” (`docs/ARCHITECTURE.md`, `docs/SYSTEM_OVERVIEW.md`, `apps/box-stats-api/src/app.module.ts`, `apps/box-stats-api/src/feature/stats-events/*`) - Recommendation APIs (similar ads/videos + “guess you like”) are implemented but not mentioned in architecture/roadmap (`apps/box-app-api/src/feature/recommendation/*`) - RabbitMQ resilience layer with fallback replay + DLQ for stats events exists but is not called out in early planning docs (`apps/box-app-api/src/rabbitmq/rabbitmq-publisher.service.ts`, `apps/box-app-api/src/rabbitmq/rabbitmq-fallback-replay.controller.ts`) - Dev-only cache tooling and production cache-admin endpoints exist beyond high-level planning notes (`apps/box-mgnt-api/src/dev/*`, `apps/box-mgnt-api/src/cache-sync/*`) ### 2. Planned items that are not implemented - TODO: delete video media endpoint (`apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.controller.ts`) - TODO: cache rebuild for HOME/CHANNEL/TRENDING lists (`apps/box-mgnt-api/src/cache-sync/cache-sync.service.ts`) - TODO: tag-based ad aggregation (`apps/box-stats-api/src/feature/stats-events/stats-aggregation.service.ts`) - TODO: refactors after schema changes for video list cache (`libs/core/src/cache/video/list/video-list-cache.builder.ts`) - Planned “optimization/scalability/monitoring” phases are not represented as concrete modules in code (Phase 5–8 in `docs/ROADMAP.md`) ### 3. Design decisions that diverged from early planning - “Stats API (future/upcoming)” in planning docs diverges from code that already implements and wires it (`docs/ARCHITECTURE.md`, `docs/SYSTEM_OVERVIEW.md`, `apps/box-stats-api/src/*`) - “Redis-first with Mongo fallback (future extension)” diverges from app code that directly uses Mongo Prisma in multiple services (`apps/box-app-api/src/feature/*/*.service.ts`) ### 4. Irreversible decisions (schema, contracts, public APIs) - Database schemas are established in Prisma for MySQL/Mongo/MongoStats (`prisma/mysql/schema/*.prisma`, `prisma/mongo/schema/*.prisma`, `prisma/mongo-stats/schema/*.prisma`) - Public API route structure is fixed to `/api/v1` and `/api/v1/mgnt/*` with specific controllers already defined (`apps/*/src/main.ts`, `apps/box-mgnt-api/src/mgnt-backend/mgnt-backend.module.ts`, controller files under `apps/box-app-api/src/feature/*` and `apps/box-mgnt-api/src/mgnt-backend/*`) - Stats ingestion routes and internal debug endpoints are defined and exposed in code, creating implied contracts (`apps/box-app-api/src/feature/stats/stats.controller.ts`, `apps/box-stats-api/src/feature/stats-events/stats-internal.controller.ts`) ## Resume Checklist - Safe to continue: `apps/box-app-api/src/feature/homepage`, `apps/box-app-api/src/feature/sys-params`, `apps/box-mgnt-api/src/mgnt-backend/feature/tag`, `apps/box-mgnt-api/src/mgnt-backend/feature/category`, `apps/box-mgnt-api/src/mgnt-backend/feature/channel`, `apps/box-mgnt-api/src/mgnt-backend/feature/system-params` (isolated CRUD, clear module wiring) - Fragile—don’t touch without tests: auth/guards (`apps/box-mgnt-api/src/mgnt-backend/core/auth`, `apps/box-app-api/src/feature/auth`), cache sync/warmups (`apps/box-mgnt-api/src/cache-sync`, `libs/core/src/cache/*`), RabbitMQ publisher/consumer (`apps/box-app-api/src/rabbitmq`, `apps/box-stats-api/src/feature/rabbitmq`) - Missing glue code blocking features: TODOs in cache rebuild paths (`apps/box-mgnt-api/src/cache-sync/cache-sync.service.ts`), video list cache refactors (`libs/core/src/cache/video/list/video-list-cache.builder.ts`), video media delete endpoint (`apps/box-mgnt-api/src/mgnt-backend/feature/video-media/video-media.controller.ts`) - Unknowns to clarify before new work: route prefixing ambiguity (`apps/box-app-api/src/feature/recommendation/recommendation.controller.ts` vs global prefix), auth expectations for `GET /api/v1/video/recommended`, stats internal endpoints access model, required env vars for S3 usage (`apps/box-mgnt-api/src/mgnt-backend/feature/s3/s3.service.ts`) and RabbitMQ availability expectations