Release: Relapse Analytics, AI Recovery Enhancements, and Daily Challenge Features#3
Merged
Conversation
…gration - extend user model with porn_free_goal column and validation - update onboarding request/validation to require porn_free_goal - persist AI onboarding analysis summary in profile - enhance service to call AI analyzer and return analysis payload - update OpenAPI specs, docs, and migrations for new field - adjust tests and routes to handle porn_free_goal and analysis data - ensure idempotent onboarding with AI summary persistence
- update documentation to include new migration for manual auth columns - modify auth docs with baseline seeder details and review date - add baseline user fixture with email/password authentication - adjust seed script to use email, username, password_hash and handle conflicts - update duplicate‑google‑id check to ignore null values in deployment script - revise integration test to match new duplicate‑check query - ensure idempotent seeding and documentation of fixture credentials
- remove duplicate usersService creation - inject aiService into usersmodule.NewService - update constructor arguments order - ensure proper dependency injection for AI telemetry - improve test harness setup readability - maintain existing service functionality - prevent nil pointer issues in tests
- implement `/api/v1/ai/relapse-solution` handler, route, and service - add request/response DTOs and validation for mood, relapse triggers, and commitment - generate AI relapse solution with system instruction and fallback plan - extend routine service to call AI advisor on relapse check‑ins and return solution payload - update OpenAPI schema: new models, fields (day names, attempts, success rate, weekday summary, streak goal comparison) - enhance docs and route tables to include the new AI endpoint and updated statistics fields - add database migration for `relapse_trigger` as text[] and related model changes.
- introduce POST /api/v1/routine/relapses for recording daily relapse triggers - implement RelapseRequest, RelapseInput, and validation rules separating relapse from check-in - add repository methods for relapse CRUD and upsert journal handling - update service layer to process relapse creation, sync streaks, and return statistics with solution - adjust statistics computation to include relapse data and update activity summary logic - update tests and OpenAPI documentation to reflect new relapse endpoint and behavior - ensure idempotency, unique constraints, and proper error handling for relapse records
- update service to store assistant role instead of model - normalize chat history role in responses - add validation for allowed onboarding levels - extend tests for role normalization and invalid level handling - synchronize OpenAPI messages and documentation updates - add flow and endpoint audit documentation and update operation index - adjust related docs and contract references accordingly
- include github.com/lib/pq v1.10.9 in go.mod - remove indirect comment for duplicate entry - ensure proper version alignment with other db packages - update module requirements for PostgreSQL support - no code changes required - prepares for future db migrations - maintain go.mod consistency
…mments, and daily challenges
seed: expand baseline data for education contents, community posts/co…
- add check for relapse on the same UTC day before updating streak - close active streak when a same‑day relapse is found - exclude check‑ins on relapse days from streak and statistics calculations - update statistics computation to ignore days with both relapse and successful check‑in - ensure `current_streak` resets to 0 if today has a relapse - prevent double‑counting of legacy relapse records - add tests for statistics and streak sync behavior with same‑day relapse.
- introduce `type` column with enum (artikel, video) in DB schema and migrations - update OpenAPI spec to include `type` in education content responses - modify DTO, service, and model structs to handle `type` and normalize category labels - add documentation notes and update seed data to reflect new `type` values - enhance tests to verify presence and correctness of `type` and label formatting - include migration scripts for cleanup of category label formatting.
… refresh tokens - add google_id column handling in user seed - populate relapse_trigger based on mood in check‑in seed - insert extensive education content about porn addiction impacts - generate relapse records from recent failed check‑ins - seed auth_refresh_tokens with hash‑only entries - update upsert logic for users and check‑ins to include new fields - ensure conflict resolution updates new columns appropriately
- define new DTOs for relapse statistics payload - implement GetRelapseStatistics handler - add repository method to fetch user profile - compute hourly relapse distribution and peak hours - integrate AI summary fallback and time‑summary generation - register new route `/relapses/statistics` - update OpenAPI spec and documentation accordingly
- include `porn_free_goal` in OpenAPI spec for user endpoints - update generated docs to reflect new field - document field requirement in user module documentation - extend user route tests to verify presence and value of `porn_free_goal` - ensure model serialization includes `porn_free_goal` in responses - maintain backward compatibility by allowing integer or null - update related test fixtures with sample goal value
- introduce `relapse_calendar` field in statistics responses - update OpenAPI specs and component schemas accordingly - modify AI relapse solution schema to use `summary` instead of `action_steps` - add new endpoint `/routine/relapses/statistics` with full relapse stats - update documentation tables and module docs to reflect new fields and endpoint - adjust AI service to generate analysis and summary for relapse solutions - update tests to cover new fields and behavior changes
- extend OpenAPI schema with porn_free_goal integer field - update documentation to include porn_free_goal in user settings - add PornFreeGoal to SettingsUpdateRequest DTO - implement validation for porn_free_goal range (1‑3650 days) - ensure validator normalizes porn_free_goal updates - add tests for successful update and out‑of‑range validation - propagate changes to generated OpenAPI docs bundle
- bump last_reviewed to 2026-05-15 - add platform endpoints (health, metrics, openapi, docs) - restructure tables for clarity and alignment - include achievements endpoints in inventory - update contract fields table with platform routes note - adjust gap register date reference - improve markdown formatting for tables
- introduce `relapse_triggers_distribution` in OpenAPI spec - add `RelapseTriggerStatPayload` DTO and compute trigger stats - replace `latest_relapse_solution` with `relapse_trigger_summary` in responses - update documentation and tests to reflect new fields - adjust service logic to generate trigger distribution and summary - ensure fallback behavior works with renamed fields - update generated OpenAPI docs accordingly
- include mandatory signature marker in system instructions - define detailed style blocks for friendly, concise, direct, and supportive personas - update tests to verify presence and uniqueness of each persona signature - ensure persona instructions enforce consistent tone and structure - prevent mixing styles across personas - add validation for signature presence in provider requests - improve documentation of persona behavior within service code
- remove backend UTC note from analysis text - keep concise user-facing message - maintain existing title and summary content - ensure generated timestamp format unchanged - update related payload construction - no functional logic changes - improve readability for end users
- extend OpenAPI schema with title/description for challenges and new physical_challenge object - update API docs and reference tables to include physical challenge fields - modify database docs and migration scripts to create daily_physical_challenges table - add repository method ListActivePhysicalChallenges and corresponding model - update DTOs and service to return physical challenge payload with fallbacks - adjust tests and seed data for physical challenges - ensure idempotent seeding and documentation reflect new content type
- add regex-based sanitization helper to remove internal persona tokens - integrate sanitization in AskCoach response and stored messages - update service tests to verify stripped markers in replies and DB rows - modify persona style instructions to include signature_id markers - ensure system instruction contains signature_id for persona selection - add utility functions for detecting and stripping marker lines/tokens - improve documentation comments for new sanitization behavior
- adjust INSERT statement to explicitly cast id as uuid - ensure compatibility with uuid column type - prevent type mismatch errors during seed execution - maintain existing data integrity in daily_challenges table - update migration seed script for consistent schema usage - add comment clarifying the need for casting - run migration tests to verify successful insertion
- update last reviewed date in education module docs - add label category Title Case rule to education docs - enforce latest schema constraints in database seeding docs - specify user‑facing label format (natural + Title Case) in seeding guide - rename content categories to Title Case in baseline seed SQL - add title and description columns to daily challenges insert statements - ensure idempotent inserts respect new schema constraints
There was a problem hiding this comment.
Pull request overview
PR ini membawa rilis fitur recovery baru ke API Recova, termasuk pencatatan relapse terpisah + analitik lanjutan, integrasi AI untuk analisis onboarding/relapse solution, perluasan daily content (termasuk tantangan fisik), serta normalisasi metadata education.
Changes:
- Menambah model + migrasi untuk
relapses,porn_free_goal,education_contents.type, dandaily_physical_challenges, serta memperluas seed baseline agar kompatibel dengan schema terbaru. - Memperkenalkan endpoint relapse terpisah (
POST /routine/relapses) dan statistik relapse lengkap (GET /routine/relapses/statistics) beserta perubahan payload statistik (calendar, weekday summary, goal comparison). - Menguatkan AI layer: sanitasi response coach (anti persona leakage), normalisasi role chat history ke
assistant, analisis onboarding wajib, dan endpoint AI relapse-solution.
Reviewed changes
Copilot reviewed 77 out of 80 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| test/integration/scripts_test.sh | Update query matcher untuk duplikasi google_id non-null |
| test/harness/e2e/runtime.go | Update wiring users service + seed reference content (education type, challenge details) |
| test/e2e/critical_flows_test.go | Tambah field onboarding porn_free_goal pada E2E flow |
| test/contract/openapi_contract_test.go | Tambah coverage kontrak untuk endpoint relapse & porn_free_goal |
| scripts/staging-deploy.sh | Perbaiki cek duplikasi google_id agar abaikan NULL |
| migrations/seeds/000001_baseline_seed.sql | Perluas baseline seed (manual auth, porn_free_goal, relapse_trigger, relapses, daily physical challenges) |
| migrations/20260515102000_add_daily_physical_challenge_and_challenge_details.up.sql | Tambah title/description ke daily_challenges + buat tabel daily_physical_challenges |
| migrations/20260515102000_add_daily_physical_challenge_and_challenge_details.down.sql | Rollback perubahan daily challenges + drop daily_physical_challenges |
| migrations/20260514215000_cleanup_user_facing_category_labels.up.sql | Normalisasi education_contents.category underscore -> spasi |
| migrations/20260514215000_cleanup_user_facing_category_labels.down.sql | Partial rollback kategori education (spasi -> underscore untuk subset) |
| migrations/20260514214000_add_education_content_type.up.sql | Tambah kolom education_contents.type + constraint enum |
| migrations/20260514214000_add_education_content_type.down.sql | Rollback kolom/constraint type education |
| migrations/20260514153000_create_relapses_table.up.sql | Buat tabel relapses + index + FK |
| migrations/20260514153000_create_relapses_table.down.sql | Drop tabel/index relapses |
| migrations/20260514090000_alter_relapse_trigger_to_text_array.up.sql | Ubah check_ins.relapse_trigger ke text[] |
| migrations/20260514090000_alter_relapse_trigger_to_text_array.down.sql | Rollback relapse_trigger array -> text |
| migrations/20260513124500_add_relapse_trigger_to_checkins.up.sql | Tambah kolom relapse_trigger di check_ins |
| migrations/20260513124500_add_relapse_trigger_to_checkins.down.sql | Drop kolom relapse_trigger di check_ins |
| migrations/20260513101500_add_porn_free_goal_to_users.up.sql | Tambah users.porn_free_goal + check constraint |
| migrations/20260513101500_add_porn_free_goal_to_users.down.sql | Rollback porn_free_goal constraint/column |
| internal/platform/database/models/core_models.go | Tambah field-model (porn_free_goal, relapse_trigger array, relapses, education type, challenge details, daily physical challenge) |
| internal/modules/users/validator.go | Validasi porn_free_goal untuk settings + onboarding |
| internal/modules/users/validator_test.go | Test coverage porn_free_goal (settings + onboarding) |
| internal/modules/users/service.go | Onboarding memanggil AI analyzer + persist ai summary + return analysis payload |
| internal/modules/users/service_test.go | Tambah test analyzer onboarding + porn_free_goal behavior |
| internal/modules/users/route_test.go | Pastikan porn_free_goal muncul di response /users/me |
| internal/modules/users/repository.go | Persist porn_free_goal + ai summary saat CompleteOnboarding; reset juga menghapus porn_free_goal |
| internal/modules/users/dto.go | Tambah field porn_free_goal + onboarding_analysis payload |
| internal/modules/routine/validator.go | Pisahkan relapse flow: check-in wajib sukses; relapse trigger hanya via endpoint relapse |
| internal/modules/routine/validator_test.go | Test aturan baru check-in vs relapse |
| internal/modules/routine/service.go | Tambah create relapse, statistik relapse lengkap, kalender relapse, weekday summary, goal comparison, AI relapse solution hooks |
| internal/modules/routine/service_test.go | Tambah test statistik enhanced + same-day relapse rules + relapse statistics |
| internal/modules/routine/route.go | Register route relapse create + relapse statistics |
| internal/modules/routine/route_test.go | Test endpoint relapse + field baru statistik + relapse statistics |
| internal/modules/routine/repository.go | Tambah query profile, relapse CRUD/list, upsert journal helper |
| internal/modules/routine/handler.go | Handler CreateRelapse + GetRelapseStatistics |
| internal/modules/routine/dto.go | Payload diperluas: day_name, relapse triggers, relapse solution, relapse statistics structures |
| internal/modules/education/service.go | Normalisasi kategori user-facing + normalisasi type |
| internal/modules/education/service_test.go | Test normalisasi kategori + fallback type |
| internal/modules/education/route_test.go | Pastikan response education punya type & kategori tanpa underscore |
| internal/modules/education/repository_integration_test.go | Update integration test untuk kolom type |
| internal/modules/education/dto.go | Tambah field type ke payload education |
| internal/modules/content/service.go | Daily content kini mengembalikan challenge + physical challenge (title/description) |
| internal/modules/content/service_test.go | Update test untuk payload challenge object + physical challenge fallback |
| internal/modules/content/seed_integration_test.go | Seed count menambahkan daily_physical_challenges |
| internal/modules/content/route_test.go | Stub repo menambahkan physical challenges |
| internal/modules/content/repository.go | Implement ListActivePhysicalChallenges |
| internal/modules/content/dto.go | Daily content payload berubah (challenge object + physical_challenge) |
| internal/modules/auth/validator.go | Onboarding auth validator menambahkan porn_free_goal validation |
| internal/modules/auth/validator_test.go | Test onboarding auth termasuk porn_free_goal |
| internal/modules/auth/service.go | User payload menambahkan porn_free_goal |
| internal/modules/auth/dto.go | Tambah porn_free_goal di user payload + onboarding request/input |
| internal/modules/ai/validator.go | Validasi request relapse-solution + helper normalize |
| internal/modules/ai/validator_test.go | Test request relapse-solution |
| internal/modules/ai/service.go | Sanitasi coach reply, normalisasi role, tambah relapse-solution generator, hardening onboarding level |
| internal/modules/ai/service_test.go | Test sanitasi persona leak, role normalization, invalid onboarding level, relapse-solution |
| internal/modules/ai/route.go | Tambah route /ai/relapse-solution |
| internal/modules/ai/route_test.go | Test endpoint relapse-solution |
| internal/modules/ai/handler.go | Handler relapse-solution |
| internal/modules/ai/dto.go | DTO relapse-solution request/response/input |
| internal/app/bootstrap/application.go | Wire aiService ke routine & users service (onboarding analyzer, relapse advisor) |
| go.mod | Tambah dependency github.com/lib/pq untuk StringArray |
| docs/operations/index.md | Tambah entry audit doc + update last_reviewed |
| docs/operations/flow-and-endpoint-audit-2026-05-14.md | Dokumen audit flow/endpoint baru |
| docs/operations/database-seeding.md | Update aturan seeding (physical challenges, schema constraints) |
| docs/modules/users.md | Dokumentasi rules porn_free_goal & behavior endpoint users |
| docs/modules/streaks.md | Update rule streak: relapse same-day & goal comparison |
| docs/modules/statistics.md | Update kontrak statistik & penambahan endpoint relapse statistics |
| docs/modules/routine.md | Update kontrak routine: endpoint relapse, rules validasi, behavior same-day relapse |
| docs/modules/onboarding.md | Dokumentasi onboarding + analisis AI onboarding + porn_free_goal |
| docs/modules/education.md | Dokumentasi type + format kategori user-facing |
| docs/modules/daily-content.md | Dokumentasi daily content termasuk physical challenge |
| docs/modules/check-ins.md | Dokumentasi check-in + relapse endpoint terpisah |
| docs/modules/auth.md | Dokumentasi onboarding auth mencakup porn_free_goal + onboarding_analysis |
| docs/modules/ai-coach.md | Dokumentasi AI coach termasuk relapse-solution endpoint |
| docs/generated/routes.md | Update inventory routes runtime (+ relapse endpoints, + AI relapse-solution) |
| docs/database.md | Update dokumentasi entitas DB untuk physical challenges + manual auth + porn_free_goal |
| docs/api-reference.md | Update endpoint inventory + kontrak coverage status |
Comments suppressed due to low confidence (2)
internal/modules/routine/service.go:664
- The
relapsesloop incomputeActivitySummaryunconditionally incrementsrelapseCountand appends aType: "relapse"activity item. When a legacy failed check-in for the same day also exists, this will double-count relapses and create two timeline items (checkin_relapse+relapse) for one UTC date. Add a guard to skiprelapsesrows whoserelapse_dateis already represented by an unsuccessful check-in for that day (or otherwise de-duplicate by day).
docs/api-reference.md:132 - In "Source Reference", there are absolute local paths (including a path to a different repo:
/Users/macbookpro/Development/bisakerja-api/...). These references won’t resolve for readers and may be misleading. Prefer repo-relative links or remove external local paths in favor of canonical upstream URLs.
## Source Reference
- [references/README.md](/Users/macbookpro/Development/recova-backend-v2/references/README.md)
- [/Users/macbookpro/Development/bisakerja-api/docs/api-reference.md](/Users/macbookpro/Development/bisakerja-api/docs/api-reference.md)
- [Scalar API Reference Getting Started](https://scalar.com/products/api-references/getting-started)
- [Scalar Docs Navigation](https://scalar.com/products/docs/configuration/navigation)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+621
to
628
| if !row.IsSuccessful { | ||
| relapseCount++ | ||
| } | ||
|
|
||
| eventType := "checkin_relapse" | ||
| if row.IsSuccessful { | ||
| eventType = "checkin_success" | ||
| eventType := "checkin_success" | ||
| if !row.IsSuccessful { | ||
| eventType = "checkin_relapse" | ||
| } |
Comment on lines
+82
to
+88
| // UpsertJournalByCheckInID creates or updates journal content linked to check-in. | ||
| func (r *Repository) UpsertJournalByCheckInID(ctx context.Context, userID string, checkInID string, content string) error { | ||
| updates := r.db.WithContext(ctx). | ||
| Model(&models.Journal{}). | ||
| Where("check_in_id = ?", strings.TrimSpace(checkInID)). | ||
| Update("content", strings.TrimSpace(content)) | ||
| if updates.Error != nil { |
Comment on lines
36
to
40
| - [Testing Strategy](/Users/macbookpro/Development/recova-backend-v2/docs/operations/testing.md) | ||
| - [Verification Matrix](/Users/macbookpro/Development/recova-backend-v2/docs/operations/verification-matrix.md) | ||
| - [Flow and Endpoint Audit 2026-05-14](/Users/macbookpro/Development/recova-backend-v2/docs/operations/flow-and-endpoint-audit-2026-05-14.md) | ||
| - [CI/CD Operations](/Users/macbookpro/Development/recova-backend-v2/docs/operations/ci-cd.md) | ||
| - [Release Gates](/Users/macbookpro/Development/recova-backend-v2/docs/operations/release-gates.md) |
Comment on lines
121
to
126
| - [API Compatibility Matrix](/Users/macbookpro/Development/recova-backend-v2/docs/api-compatibility-matrix.md) | ||
| - [API Versioning Standard](/Users/macbookpro/Development/recova-backend-v2/docs/standards/api-versioning.md) | ||
| - [API Response Standard](/Users/macbookpro/Development/recova-backend-v2/docs/api-response-standard.md) | ||
| - [API Docs Generation](/Users/macbookpro/Development/recova-backend-v2/docs/operations/api-docs-generation.md) | ||
| - [Flow and Endpoint Audit (2026-05-14)](/Users/macbookpro/Development/recova-backend-v2/docs/operations/flow-and-endpoint-audit-2026-05-14.md) | ||
|
|
Comment on lines
+108
to
+111
| - [API Reference](/Users/macbookpro/Development/recova-backend-v2/docs/api-reference.md) | ||
| - [Generated OpenAPI](/Users/macbookpro/Development/recova-backend-v2/docs/generated/openapi.yaml) | ||
| - [Route Inventory](/Users/macbookpro/Development/recova-backend-v2/docs/generated/routes.md) | ||
| - [Security Operations](/Users/macbookpro/Development/recova-backend-v2/docs/operations/security.md) |
| - konten tidak aktif tidak boleh muncul di payload, | ||
| - payload item wajib selalu memuat `type` dengan nilai `artikel` atau `video`, | ||
| - label kategori user-facing harus natural (spasi), bukan snake_case, | ||
| - label kategori user-facing mengikuti Title Case konsisten (contoh: `Dampak Pornografi`), |
| - persona aktif harus dipakai saat membangun system instruction AI, | ||
| - respons `ask-coach` menyertakan `persona_used` agar audit troubleshooting mudah. | ||
| - `POST /api/v1/auth/onboarding` memanggil analisis onboarding secara internal dan menyertakan hasilnya di response onboarding. | ||
| - `POST /api/v1/routine/checkin` memanggil `relapse-solution` secara internal saat `is_successful=false`, lalu mengembalikan analisis + ringkasan solusi ke payload check-in. |
Comment on lines
+63
to
+70
| - `hourly_relapse_distribution`, | ||
| - `relapse_triggers_distribution`, | ||
| - `peak_relapse_hours_utc`, | ||
| - `peak_relapse_count`, | ||
| - `relapse_time_summary`, | ||
| - `relapse_trigger_summary`. | ||
| - `active_days`, | ||
| - `recent_activity[].day_name`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR merges new recovery-focused features, AI enhancements, and platform improvements from
developintomain, including:Notes