Image entity with polymorphic association, AWS S3 integration, and Amazon CloudFront distribution.SessionDetailScreen, SessionCalendarScreen, and the mediaService mapped to CloudFront URLs for lightning-fast image caching.| Day | Task | Start Date | Completion Date | Reference Material |
|---|---|---|---|---|
| 2 | - Build Image entity (module/media)+ Fields: url (≤500), isThumbnail, food (@ManyToOne nullable), workoutPlan (@ManyToOne nullable), exercise (@ManyToOne nullable)+ DB check constraint chk_image_exclusive: exactly ONE of food_id, workout_plan_id, exercise_id is non-null (exclusive polymorphic FK)+ Write Flyway V3 migration: image table with exclusive FK constraint | 02/24/2026 | 02/24/2026 | |
| 3 | - Build ImageController (/api/images)+ POST / — register image record (URL stored; file lives in S3)+ GET /{id}, GET /food/{foodId}, GET /workout-plan/{workoutPlanId}, GET /exercise/{exerciseId}+ PUT /{id}, DELETE /{id} | 02/25/2026 | 02/25/2026 | |
| 3 | - Configure AWS S3 integration (config/AwsS3Config.java)+ AWS SDK v1: AmazonS3 bean configured with region ap-southeast-1+ Bucket name from env S3_BUCKET_NAME (default crawl.fitness)+ Upload utility method for media files | 02/25/2026 | 02/25/2026 | https://docs.aws.amazon.com/sdk-for-java/ |
| 4 | - Build mediaService (Frontend) + getImageUrl(owner, id) — fetch image URL from GET /api/images/{owner}/{id}+ In-memory URL cache + in-flight deduplication (prevents duplicate API calls for the same image) + Bulk helpers: getFoodImageUrlMap(ids[]), getWorkoutPlanImageUrlMap(ids[]), getExerciseImageUrlMap(ids[]) | 02/26/2026 | 02/26/2026 | |
| 5 | - Build SessionDetailScreen (Frontend) + Past workout recap: exercises grouped by exerciseId+ Shows sets × reps × weight per exercise + Formatted date/time display with utils/date.ts | 02/27/2026 | 02/27/2026 | |
| 6 | - Build SessionCalendarScreen (Frontend) + Monthly calendar view with dot indicators on days that have sessions + Month navigation (prev/next chevrons) + Click a date to show session logs below the calendar + Vietnamese day/month labels (Thứ 2–CN, Tháng 1–12) | 02/28/2026 | 02/28/2026 |
s3_images_upload.json) migrated to use CloudFront domains instead of direct S3 URLs, dramatically reducing data transfer costs.SessionDetailScreen correctly groups workout logs by exercise and renders sets/reps/weight clearly.SessionCalendarScreen marks training days with dots; tap to reveal session details inline.mediaService caches fetched image URLs in memory — no duplicate API calls for images already loaded.In summary, week 7 turned S3 knowledge into a practical and secure media delivery model for the app.
Food, Meal, MealFood, DailyNutrition entities with full CRUD and nutrition calculation.DietScreen with meal management, food search, and add-food-to-meal flow.