|
|
@@ -0,0 +1,223 @@
|
|
|
+# 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
|