Diary future development notes
============================
Date: 2026-03-07

Purpose
-------
Capture the research and design ideas for adding prompt-specific required words/phrases
for Diary auto-grading, based on analysis of question/type/essayautograde and current
mod_diary architecture.

Summary of findings
-------------------
1. Diary already has prompt linkage that fits this feature:
   - diary_entries.promptid links each entry to the prompt used.
   - diary_prompts holds prompt-level settings.

2. Diary already has reusable text matching logic:
   - mod/diary/classes/local/diarystats.php has search_text(...).
   - This can be reused for phrase matching so behavior stays consistent.

3. Essay auto-grade phrase storage model (reference only):
   - Plugin examined: question/type/essayautograde
   - Autograde rules are not stored in a dedicated rules table.
   - Phrase data is packed into question_answers fields:
     - phrase text in question_answers.feedback
     - phrase percent in question_answers.feedbackformat
     - rule flags/type/divisor encoded into question_answers.fraction
   - This works, but is compact/encoded and harder to maintain for Diary.

Recommendation for Diary
------------------------
Use a dedicated Diary table for prompt autograde rules instead of encoded storage.
This will be cleaner, easier to query, easier to migrate, and simpler to maintain.

Proposed schema
---------------
New table (working name): mdl_diary_prompt_autograde_rules

Suggested fields:
- id (PK)
- diaryid (FK to mdl_diary.id)
- promptid (FK to mdl_diary_prompts.id)
- phrase (text/varchar)
- matchtype (int): exact / contains / regex (if regex is allowed)
- casesensitive (int/bool)
- fullmatch (int/bool)
- ignorebreaks (int/bool)
- weightpercent (number): contribution to phrase score
- required (int/bool): if true, missing phrase can trigger warning/penalty
- sortorder (int)
- timecreated
- timemodified
- usermodified

Index suggestions:
- (promptid)
- (diaryid, promptid)
- (promptid, sortorder)

Implementation outline
----------------------
1. Database and upgrade
   - Add new table in mod/diary/db/install.xml.
   - Add upgrade step in mod/diary/db/upgrade.php.
   - Add backup and restore mapping for the new table and all of its fields
     (include both backup export and restore import paths).
   - Bump version in mod/diary/version.php when implemented.

2. Prompt editor UI
   - Extend mod/diary/prompt_edit.php (and related form handling) to manage phrases
     per prompt (add/edit/delete/reorder).
   - Include controls for match options and weight percent.
   - Validate totals and input limits (for example, no negative weights).

3. Data access layer
   - Add helper methods in Diary local classes to:
   - fetch prompt autograde rules
     - normalize phrase config
     - evaluate entry text against configured phrases

4. Scoring integration
   - During stats/auto-rating calculation, detect entry promptid.
   - Load prompt autograde rules for that prompt only.
   - Reuse search_text(...) for phrase detection.
   - Calculate phrase contribution and merge with existing min/max metric logic.
   - Decide policy for required phrase misses:
     - warning only, or
     - grade penalty, or
     - block full phrase score.

5. Display and teacher feedback
   - Show phrase match details in report output:
     - matched phrases
     - missing required phrases
     - phrase score contribution
   - Keep output compact and readable for report.php/reportone.php/reportsingle.php.

6. Language strings
   - Add new lang strings for phrase labels/help and validation messages.
   - Ensure no hardcoded UI text.

7. Backup/restore and privacy
   - Add prompt autograde rules table to backup and restore definitions.
   - Review privacy provider export coverage if phrase settings should appear there.

8. Tests
   - PHPUnit:
     - prompt phrase CRUD
     - phrase matching cases (case-sensitive, full match, line breaks)
     - score calculations and edge cases
   - Behat:
     - prompt edit phrase workflow
     - teacher report visibility for match results

Behavior design options to decide
---------------------------------
1. Required phrase policy:
   - strict required (must exist), or soft required (warning only).
2. Match mode:
   - exact/whole-word only vs substring option.
3. Regex support:
   - allow or disallow (safety/performance implications).
4. Weight model:
   - per phrase percentages sum to 100, or independent additive weights.
5. Student visibility:
   - show required phrase checklist to students before submit, or teacher-only.
6. Grading bands:
    - add optional score bands (for example: excellent/good/fair/poor) with
       configurable boundaries, similar to Essay Autograde patterns.
    - decide whether bands are report-only labels or can also drive final grade
       mapping and teacher feedback defaults.

Grading bands (new consideration)
---------------------------------
- Candidate enhancement: support optional grading bands on top of phrase scoring,
   modeled after band-style outcomes used in Essay Autograde.
- Suggested initial scope:
   - Keep phrase scoring as the numeric source of truth.
   - Add an optional band table/config to map score ranges to labels.
   - Show the matched band in report output and (optionally) in feedback helpers.
- Suggested deferral rule:
   - Implement phrase-rule scoring first, then layer bands in a follow-up step to
      reduce rollout risk.

Design-only schema sketch (minimal)
-----------------------------------
Candidate table: mdl_diary_prompt_autograde_bands

Minimal fields:
- id (PK)
- diaryid (FK to mdl_diary.id)
- promptid (FK to mdl_diary_prompts.id)
- label (varchar): band name shown in reports/feedback helpers
- scoremin (number): inclusive lower bound
- scoremax (number): inclusive upper bound
- sortorder (int)
- timecreated
- timemodified
- usermodified

Minimal index suggestions:
- (promptid)
- (promptid, sortorder)

Why this approach is preferred
------------------------------
- Aligns with Diary prompt-centric architecture already in place.
- Avoids overloaded encoded fields used by Essay auto-grade internals.
- Improves readability and future maintenance.
- Enables straightforward reporting, migration, and testing.

Reference files examined
------------------------
Essay auto-grade:
- question/type/essayautograde/edit_essayautograde_form.php
- question/type/essayautograde/questiontype.php
- question/type/essayautograde/question.php
- question/type/essayautograde/db/install.xml

Diary:
- mod/diary/db/install.xml
- mod/diary/classes/local/diarystats.php
- mod/diary/edit.php
- mod/diary/reportone.php
- mod/diary/locallib.php

Suggested next implementation step
----------------------------------
Create the schema and upgrade patch first (table + upgrade step), then add a minimal
prompt_edit.php UI for phrase CRUD, then wire scoring in diarystats.

Mobile capability request
-------------------------
User demand note:
- Multiple users have requested Diary support in the Moodle Mobile app.

Current context:
- Upgrade notes already reference historical non-support for mobile and earlier work
  around mobile/template modernization.
- Diary now uses Mustache for reportone and has index rendering updates that can help
  a mobile rollout.

Recommended mobile roadmap
--------------------------
1. Define minimum mobile scope (phase 1)
   - Student: view prompt, create/edit entry text, view own prior entries.
   - Teacher: view entries needing grading, add feedback/rating.
   - Out of scope initially: advanced prompt admin UX and full report tooling.

2. API and external functions audit
   - Confirm required ws functions exist for entry CRUD, prompt retrieval, and feedback.
   - Add/adjust external services if gaps are found.

3. Mobile handlers/templates
   - Implement or extend mobile handlers (db/mobile.php + templates) for core Diary flows.
   - Reuse Mustache-style data shaping where possible to reduce duplicate logic.

4. Capability and privacy checks
   - Enforce addentries/manageentries capability checks in all mobile endpoints.
   - Ensure privacy/export expectations are consistent for mobile-accessed content.

5. Notifications in mobile context
   - Confirm message providers and push/email behaviors are coherent for app users.
   - Validate immediate vs delayed teacher notifications still behave as intended.

6. Offline and sync strategy
   - Decide whether to support offline draft/edit in phase 1 or defer.
   - If deferred, show clear in-app messaging to avoid data-loss expectations.

7. Testing plan
   - Behat/API tests for mobile web service responses.
   - Manual Moodle App verification on Android and iOS for student and teacher roles.

Acceptance targets for initial mobile release
--------------------------------------------
- Student can submit and edit an entry for available windows.
- Student can view prompt used and own feedback/rating.
- Teacher can open a single student entry, provide feedback/rating, and save.
- No capability leaks, and no regressions in browser-based Diary workflows.

Step 1 audit results (current state)
------------------------------------
Date: 2026-03-07

Path standard update (Moodle Academy 2026-02-10)
------------------------------------------------
- Mobile Mustache templates should be placed in `templates/mobileapp/`.
- Mobile JS source files should be placed in `js/mobileapp/`.
- This path convention should be used for new Diary mobile work to align with
   current guidance and avoid later coding-standards churn.

What exists now:
- Mobile-focused templates are present:
   - mod/diary/templates/mobile_view.mustache
   - mod/diary/templates/mobile_edit_entry.mustache
- Browser save/update logic already exists and can be reused as source logic:
   - Student entry save flow in mod/diary/edit.php
   - Teacher feedback/rating save flow in mod/diary/classes/local/results.php
- Required capabilities and message providers already exist:
   - mod/diary:addentries, mod/diary:manageentries
   - mod/diary/db/messages.php

Confirmed gaps (blocking Moodle App support):
- No Diary web service layer is currently implemented:
   - missing mod/diary/externallib.php
   - missing mod/diary/db/services.php
   - missing mod/diary/classes/external/*
- No mobile callback/handler file exists:
   - missing mod/diary/db/mobile.php (templates currently reference this in comments)
- Mobile template method names are not implemented anywhere in the plugin:
   - mod_diary_set_text
   - mod_diary_save_feedback
   - mobile_entry_edit

Conclusion:
- Diary has useful UI template groundwork, but does not yet expose app-consumable
   mobile web services/callbacks. Phase 1 should start by adding the external API
   surface and wiring it to existing Diary save logic.

Proposed files for next implementation step:
- mod/diary/externallib.php (or classes/external/*) for mobile WS methods
- mod/diary/db/services.php to register functions
- mod/diary/db/mobile.php (if using site plugin callbacks for app content routing)
- Wiring updates so mobile templates call implemented methods

Step 2 scaffolding status
-------------------------
Date: 2026-03-07

Implemented:
- Added mobile addon registration: `mod/diary/db/mobile.php`
- Added web service function registration: `mod/diary/db/services.php`
- Added mobile output handler: `mod/diary/classes/output/mobile.php`
- Added external endpoints:
   - `mod/diary/classes/external/view_diary.php`
   - `mod/diary/classes/external/set_text.php`
   - `mod/diary/classes/external/save_feedback.php`
- Added/wired templates under new path guidance:
   - `mod/diary/templates/mobileapp/mobile_view.mustache`
   - `mod/diary/templates/mobileapp/mobile_edit_entry.mustache`

Notes:
- The older `mod/diary/templates/mobile_*.mustache` files remain in place for now.
- Next pass should decide whether to retire old-path templates once app behavior is verified.

Step 3 verification status
--------------------------
Date: 2026-03-07

Runtime smoke checks completed in CLI against existing Diary records.

Verified paths:
- `mobile_course_view` returns template and JS payload as expected.
- `mobile_entry_edit` returns template payload as expected.
- `mod_diary\\external\\view_diary::execute(...)` runs successfully.
- `mod_diary\\external\\set_text::execute(...)` creates/updates entries successfully.
- `mod_diary\\external\\save_feedback::execute(...)` saves teacher feedback/rating successfully.

Fix applied during verification:
- In `mod/diary/classes/external/save_feedback.php`, replaced dependency on
   `RATING_AGGREGATE_NONE` with a direct `assessed !== 0` check to avoid
   undefined constant fatals in this execution context.

Remaining validation recommended:
- Manual Moodle App checks (Android/iOS) for student and teacher workflows.
- Final decision on retiring legacy `templates/mobile_*.mustache` files after
   app-side verification.

Tiles icon size consistency
---------------------------
Date: 2026-03-07

Context:
- The original clipping problem for the Diary icon in Tiles format appears resolved.
- Remaining visual issue: the Diary icon still appears slightly larger than neighboring activity icons.

Future development item:
- Standardize Diary icon rendered size to match core activity icon dimensions in course overview/Tiles displays.

Suggested implementation notes:
1. Verify where Diary icon size is set for course overview rendering (for example in `classes/courseformat/overview.php` and icon output paths).
2. Align icon output classes/attributes with core activity icons rather than relying on plugin-specific sizing.
3. Prefer theme-compatible CSS hooks over hardcoded inline dimensions.
4. Validate in multiple course formats/themes, including Tiles and Boost, on desktop and mobile widths.

Acceptance target:
- Diary icon visual size matches adjacent activity icons without clipping or disproportionate scaling.

Prompt Assignment Modes (Sequential, Choice, Random, Complete All, Partial Complete x of xx)
==================================================================
Date: 2026-03-27
Ticket: Diary_1454

Motivation
----------
Current prompt system enforces a sequential, time-gated model:
- Only one prompt is active at any given moment.
- Each prompt has a datestart and datestop window.
- No overlap between active prompts.

This works well for structured, time-paced assignments (for example semester-long sequence of essays with hard due dates).

However, teachers often want more flexibility:
- Offer students a choice of writing topics and let them pick.
- Assign a pool of prompts that students must complete in any order (for example, weekly writing workshop format).
- Randomly assign prompts from a pool to distribute topic load.
- Require all prompts to be completed but allow student ordering.
- Require completion of a subset from the pool (for example complete 3 of 5 prompts).

Feature Scope
-------------
Add a diary-level "prompt mode" setting that changes entry submission/viewing behavior:

Mode 1: Sequential (current/default behavior)
- Only the active (current date within start/stop window) prompt is visible/available.
- Students write entries linked to that single prompt for that window.
- Prompts do not overlap in time.
- Behavior unchanged from existing code.

Mode 2: Choice (student selects from pool)
- Multiple prompts in the pool are visible to student at once.
- Student picks one prompt and writes an entry to it.
- Can optionally limit number of choices per student (for example max 2 of 5 prompts).
- Teacher can require all prompts be eventually answered or allow flexible completion.
- Time windows ignored (no datestart/datestop filtering).

Mode 3: Random (system assigns)
- Student creates new entry; system assigns a random prompt from the pool.
- Student does not see unused prompts.
- Each entry gets one prompt; cannot reassign or swap.
- Time windows ignored.
- Useful for anonymized/balanced portfolio assessment.

Mode 4: Complete All (any order)
- All prompts in pool are visible.
- Student must eventually write an entry for each prompt.
- Student chooses order and timing.
- Time windows ignored.
- Good for thematic writing cycles or cumulative reflection assignments.

Mode 5: Partial Complete x of xx (subset required)
- All prompts in pool are visible.
- Teacher sets required prompt count x, where 1 <= x <= pool size.
- Student chooses which prompts to complete until required count is met.
- Progress indicator should show completed/required (for example 2/3 complete).
- Duplicate entries for the same prompt should not count as additional prompt completions.
- Time windows ignored.

Schema Changes Needed
---------------------
mdl_diary table (additions):
- promptmode (int): 0=sequential (default), 1=choice, 2=random, 3=completeall, 4=partialcomplete
- requiredpromptcount (int, default 0): used only when promptmode=4; 0 means unset.
- promptpoolid (int, null): FK to diary_prompt_pools.id (optional, for future grouping)

Candidate future table (deferred):
- mdl_diary_prompt_pools: if we want to explicitly group prompts into named pools
  rather than just using all prompts for the diary. For now, assume "pool" = all active
  prompts for this diary.

Candidate table for tracking student progress (needed for modes 2, 3, 4):
- mdl_diary_student_prompt_status
  - id (PK)
  - diaryid (FK)
  - userid (FK)
  - promptid (FK)
  - status (int): 0=not_started, 1=in_progress, 2=completed
  - entryid (FK, nullable): latest entry for this (user, prompt) pair
  - timecreated
  - timemodified

This would let us track whether a student has completed all required prompts in modes 2 and 4,
and whether requiredpromptcount has been satisfied in mode 5.

Logic Changes Needed
--------------------
1. Entry creation/view logic (mod/diary/edit.php, mod/diary/view.php):
   - Respect promptmode when filtering/listing available prompts for this student.
   - Mode 0 (sequential): existing datestart/datestop logic unchanged.
   - Mode 1 (choice): show all non-expired prompts; let student pick one; store selection.
   - Mode 2 (random): auto-assign one prompt on entry create; don't show chooser.
    - Mode 3 (completeall): show all prompts; prevent duplicate entries for same prompt.
    - Mode 4 (partialcomplete): show all prompts; allow completion until requiredpromptcount
       is met; prevent duplicate entries for same prompt from incrementing completion.

2. Grading and reporting (mod/diary/reportone.php, mod/diary/reportsingle.php, mod/diary/classes/local/results.php):
   - Group entries by prompt instead of purely by date window.
   - In mode 3 (completeall), track completion status per student per prompt and highlight gaps.
   - In mode 4 (partialcomplete), show completed/required progress and remaining needed count.
   - Show which prompts student has/hasn't answered.

3. Teacher grading UI:
   - In mode 1+ (choice/random/completeall/partialcomplete), allow filtering/grouping entries by prompt.
   - Show completion matrix: student × prompt with entry count or completion badge.

4. Availability checks:
   - Mode 0: continue using datestart/datestop + maxentries logic.
   - Mode 1-4: datestart/datestop no longer apply; validate maxentries per diary only.

Behavior Design Decisions Needed
--------------------------------
1. Required vs optional in modes 1-4:
   - Can a student skip a prompt in choice/completeall/partialcomplete mode, or are all required?
   - Add an "optional" flag per prompt?

1a. Partial complete thresholds:
   - Should x be constrained to 1..poolsize at save-time and runtime?
   - If pool shrinks after entries exist, should requiredpromptcount auto-adjust?
   - Should completed count be based on unique prompts only (recommended)?

2. Constraints per prompt in choice mode:
   - Can student answer same prompt multiple times, or once per prompt?
   - If multiple, do all entries count toward grading or just the latest?

3. Grade calculation for multi-prompt scenarios:
   - If student completes 3 of 5 prompts in choice mode, is final grade a weighted avg or only of completed?
   - Should incomplete prompts incur a penalty?

4. Deadline enforcement:
   - If promptmode > 0, ignore datestart/datestop entirely for availability?
   - Or add a single diary-level deadline (for example end-of-week cutoff) that applies to all mode 1+ prompts?

5. Student visibility:
   - In completeall mode, show a progress indicator (3 of 5 prompts completed)?
   - In choice mode, show which prompts student hasn't picked yet?
   - In partialcomplete mode, show completed/required plus remaining prompts needed?

Implementation Roadmap (Suggested)
----------------------------------
Phase 1: Data layer + sequential default
- Add promptmode column to mdl_diary schema.
- Update install.xml and upgrade.php.
- Ensure mode 0 (current behavior) works unchanged.
- Bump version.

Phase 2: Choice mode UI and logic
- Extend mode/entry.php to show prompt chooser when promptmode=1.
- Update view.php to list available prompts for selection.
- Wire entry creation to record chosen promptid.
- Add prompt selection to grading reports.

Phase 3: Random, complete-all, and partial-complete modes
- Implement auto-assignment logic for mode 2.
- Add prompt_status tracking for mode 3.
- Add requiredpromptcount logic and threshold checks for mode 4.
- Update reports to show completion matrix.

Phase 4: Teacher workflow and reporting
- Admin page to switch promptmode per diary.
- Report enhancements: prompt-grouped view, completion badges, progress indicators.

Phase 5: Mobile support
- Extend mobile templates to show prompt chooser (mode 1) and completion status
   (mode 3 and mode 4 partial-complete progress).
- Ensure WS endpoints return prompt list and mode context data.

Testing Checklist (for all modes)
---------------------------------
- Existing sequential entries still grade and display correctly in mode 0.
- Choice mode: student can pick one of many; grading works; report shows picks.
- Random mode: entries are assigned different prompts; assignments are durable (don't change on refresh).
- Complete-all mode: student see completion progress; cannot duplicate prompt; all prompts eventually visible.
- Partial-complete mode: student can complete any prompts until threshold x is met; progress and
   remaining-needed count update correctly; duplicate prompt attempts do not increase completion.
- Grading: all modes integrate with existing min/max/phrase autograde logic.
- Backward compatibility: upgrading from current (implicitly mode 0) doesn't break existing entries/grades.
- Privacy export includes prompt assignments and completion status.

Notes
-----
This feature significantly increases prompt flexibility and aligns Diary with
assignment workflows used in more open-ended, portfolio, or choice-based pedagogies.
The complexity scales with mode; phase-by-phase rollout will allow for careful
validation and user feedback before full deployment.
