diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-01-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-01-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-01-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-01-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-01-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-01-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-01-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-01-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-02-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-02-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-02-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-02-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-02-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-02-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-02-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-02-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-03-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-03-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-03-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-03-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-03-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-03-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-03-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-03-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-04-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-04-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-04-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-04-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-04-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-04-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-04-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-04-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-05-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-05-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-05-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-05-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-05-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-05-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-05-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-05-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-06-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-06-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-06-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-06-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-06-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-06-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-06-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-06-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-07-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-07-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-07-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-07-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-07-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-07-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-07-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-07-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-08-PLAN.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-08-PLAN.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-08-PLAN.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-08-PLAN.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-08-SUMMARY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-08-SUMMARY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-08-SUMMARY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-08-SUMMARY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-CONTEXT.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-CONTEXT.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-CONTEXT.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-CONTEXT.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-DISCUSSION-LOG.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-DISCUSSION-LOG.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-DISCUSSION-LOG.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-DISCUSSION-LOG.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-PATTERNS.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-PATTERNS.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-PATTERNS.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-PATTERNS.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-RESEARCH.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-SECURITY.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-SECURITY.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-SECURITY.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-SECURITY.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-UAT.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-UAT.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-UAT.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-UAT.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-UI-SPEC.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-UI-SPEC.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-UI-SPEC.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-UI-SPEC.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-VALIDATION.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-VALIDATION.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-VALIDATION.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-VALIDATION.md diff --git a/.planning/phases/08-stack-upgrade-backend-decomposition/08-VERIFICATION.md b/.planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-VERIFICATION.md similarity index 100% rename from .planning/phases/08-stack-upgrade-backend-decomposition/08-VERIFICATION.md rename to .planning/milestones/v0.2-phases/08-stack-upgrade-backend-decomposition/08-VERIFICATION.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-01-PLAN.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-01-PLAN.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-01-PLAN.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-01-PLAN.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-01-SUMMARY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-01-SUMMARY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-01-SUMMARY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-01-SUMMARY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-02-PLAN.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-02-PLAN.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-02-PLAN.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-02-PLAN.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-02-SUMMARY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-02-SUMMARY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-02-SUMMARY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-02-SUMMARY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-03-PLAN.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-03-PLAN.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-03-PLAN.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-03-PLAN.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-03-SUMMARY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-03-SUMMARY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-03-SUMMARY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-03-SUMMARY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-04-PLAN.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-04-PLAN.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-04-PLAN.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-04-PLAN.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-04-SUMMARY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-04-SUMMARY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-04-SUMMARY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-04-SUMMARY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-05-PLAN.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-05-PLAN.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-05-PLAN.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-05-PLAN.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-05-SUMMARY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-05-SUMMARY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-05-SUMMARY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-05-SUMMARY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-CONTEXT.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-CONTEXT.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-CONTEXT.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-CONTEXT.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-DISCUSSION-LOG.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-DISCUSSION-LOG.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-DISCUSSION-LOG.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-DISCUSSION-LOG.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-PATTERNS.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-PATTERNS.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-PATTERNS.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-PATTERNS.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-RESEARCH.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-RESEARCH.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-RESEARCH.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-RESEARCH.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-REVIEW.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-REVIEW.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-REVIEW.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-REVIEW.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-SECURITY.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-SECURITY.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-SECURITY.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-SECURITY.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-UAT.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-UAT.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-UAT.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-UAT.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-VALIDATION.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-VALIDATION.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-VALIDATION.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-VALIDATION.md diff --git a/.planning/phases/09-admin-panel-rearchitecture/09-VERIFICATION.md b/.planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-VERIFICATION.md similarity index 100% rename from .planning/phases/09-admin-panel-rearchitecture/09-VERIFICATION.md rename to .planning/milestones/v0.2-phases/09-admin-panel-rearchitecture/09-VERIFICATION.md diff --git a/.planning/phases/10-ux-interaction/10-01-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-01-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-01-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-01-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-01-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-01-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-01-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-01-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-02-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-02-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-02-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-02-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-02-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-02-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-02-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-02-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-03-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-03-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-03-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-03-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-03-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-03-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-03-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-03-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-04-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-04-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-04-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-04-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-04-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-04-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-04-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-04-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-05-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-05-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-05-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-05-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-05-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-05-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-05-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-05-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-06-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-06-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-06-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-06-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-06-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-06-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-06-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-06-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-07-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-07-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-07-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-07-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-07-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-07-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-07-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-07-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-08-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-08-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-08-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-08-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-08-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-08-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-08-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-08-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-09-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-09-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-09-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-09-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-09-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-09-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-09-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-09-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-10-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-10-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-10-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-10-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-10-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-10-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-10-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-10-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-11-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-11-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-11-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-11-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-11-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-11-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-11-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-11-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-12-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-12-PLAN.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-12-PLAN.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-12-PLAN.md diff --git a/.planning/phases/10-ux-interaction/10-12-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-12-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-12-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-12-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/10-ux-interaction/10-13-PLAN.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-13-PLAN.md new file mode 100644 index 0000000..ea68d5a --- /dev/null +++ b/.planning/milestones/v0.2-phases/10-ux-interaction/10-13-PLAN.md @@ -0,0 +1,393 @@ +--- +phase: 10-ux-interaction +plan: 13 +type: execute +wave: 1 +depends_on: [] +files_modified: + - frontend/src/components/ui/TreeItem.vue + - frontend/src/components/storage/StorageBrowser.vue + - frontend/src/App.vue + - frontend/src/components/documents/SearchBar.vue + - frontend/src/components/layout/OsDragOverlay.vue + - frontend/src/__tests__/keyboard.test.js + - frontend/src/components/ui/__tests__/TreeItem.test.js + - frontend/src/components/storage/__tests__/StorageBrowser.showSearch.test.js +autonomous: true +requirements: [UX-02, UX-03, UX-05, UX-06, UX-07, UX-08, UX-09] +gap_closure: true + +must_haves: + truths: + - "Sidebar Cloud/Folder sections show animated shimmer rows while async data loads — no 'Loading…' text visible" + - "Admin routes (/admin/*) render with no AppSidebar — AdminLayout is the sole layout component" + - "Pressing '/', 'U', or 'N' in the file manager dispatches to the actual FileManagerView instance — not a RouterView proxy" + - "Pressing Escape in the search input clears the field and preserves focus — no browser-native blur" + - "Dropping an OS file on the drag overlay triggers upload — capture-phase window listener fires before folder-row handlers" + - "Search bar and sort controls are visible at the root of both local and cloud file browsers" + artifacts: + - path: "frontend/src/components/ui/TreeItem.vue" + provides: "Three animate-pulse shimmer rows in the v-if='loading' branch" + contains: "animate-pulse" + - path: "frontend/src/components/storage/StorageBrowser.vue" + provides: "showSearch computed returns true for mode === 'local' OR mode === 'cloud'" + - path: "frontend/src/App.vue" + provides: "Third template branch for admin routes (no AppSidebar); getFileManagerInstance() via matched.find for keyboard dispatch" + - path: "frontend/src/components/documents/SearchBar.vue" + provides: "@keydown.escape.prevent.stop suppresses browser native blur on type='search'" + - path: "frontend/src/components/layout/OsDragOverlay.vue" + provides: "window drop listener registered with capture=true; removeEventListener also passes true" + key_links: + - from: "frontend/src/App.vue (onKeydown)" + to: "FileManagerView.focusSearch / triggerUpload / startNewFolder" + via: "router.currentRoute.value.matched.find(r => r.instances?.default)?.instances?.default" + pattern: "instances\\.default" + - from: "frontend/src/components/layout/OsDragOverlay.vue" + to: "window drop event" + via: "addEventListener('drop', handler, true)" + pattern: "addEventListener.*drop.*true" +--- + + +Close all 6 UAT gaps from 10-UAT.md that block Phase 10 sign-off: sidebar shimmer (Gap 1), search-at-root visibility (Gap 2), admin sidebar bleed (Gap 3), keyboard shortcuts broken by RouterView proxy (Gap 4 — covers tests 11, 12, 13), Escape-breaks-search (Gap 5), and OS drag-drop not uploading (Gap 6). + +Purpose: Phase 10 is recorded complete in ROADMAP.md but UAT (10-UAT.md) shows 9 issues with 6 distinct root causes diagnosed. These targeted fixes close all 6 causes with minimal code change, restoring full UAT pass. + +Output: Five production files modified, three test files added. No new dependencies. No regressions. + + + +@/Users/nik/.claude/get-shit-done/workflows/execute-plan.md +@/Users/nik/.claude/get-shit-done/templates/summary.md + + + +@/Users/nik/Documents/Progamming/document_scanner/.planning/PROJECT.md +@/Users/nik/Documents/Progamming/document_scanner/.planning/ROADMAP.md +@/Users/nik/Documents/Progamming/document_scanner/.planning/STATE.md +@/Users/nik/Documents/Progamming/document_scanner/.planning/phases/10-ux-interaction/10-UAT.md + + + + +From frontend/src/App.vue (current full state — relevant sections): +```html + + +
+ +
+ +
+
+ + +``` +```js +// script setup +import { ref, onMounted, onUnmounted } from 'vue' +import { useRoute } from 'vue-router' +const route = useRoute() +const routeViewRef = ref(null) // ← remove this + +function onOsFilesDropped(files) { + routeViewRef.value?.handleOsDrop?.(files) // ← fix to use getFileManagerInstance() +} +function onKeydown(e) { + // guard: INPUT/TEXTAREA/SELECT/contentEditable + dialog check omitted here + routeViewRef.value?.focusSearch?.() // line 37 ← fix + routeViewRef.value?.clearSearch?.() // line 40 ← fix + routeViewRef.value?.triggerUpload?.() // line 43 ← fix + routeViewRef.value?.startNewFolder?.() // line 46 ← fix +} +``` + +From frontend/src/router/index.js — admin route meta: +```js +{ + path: '/admin', + component: () => import('../layouts/AdminLayout.vue'), + meta: { requiresAdmin: true }, // only on parent; children resolved via matched.some() + children: [/* AdminOverviewView, AdminUsersView, AdminQuotasView, AdminAiView, AdminAuditView */] +} +``` + +From frontend/src/components/ui/TreeItem.vue — loading branch to replace (lines 48-52): +```html +
+ Loading… +
+``` + +Shimmer pattern to replicate (from AppSidebar.vue lines 60-64): +```html +
+
+
+
+
+
+``` + +From frontend/src/components/storage/StorageBrowser.vue line 287: +```js +const showSearch = computed(() => props.mode === 'local' && props.breadcrumb.length > 0) +// TARGET STATE: +const showSearch = computed(() => props.mode === 'local' || props.mode === 'cloud') +``` + +From frontend/src/components/documents/SearchBar.vue line 11: +```html +@keydown.escape="emit('update:modelValue', '')" + +@keydown.escape.prevent.stop="emit('update:modelValue', '')" +``` + +From frontend/src/components/layout/OsDragOverlay.vue (Options API — lines 52-63): +```js +mounted() { + window.addEventListener('dragenter', this.onDragEnter) + window.addEventListener('dragleave', this.onDragLeave) + window.addEventListener('dragover', this.onDragOver) + window.addEventListener('drop', this.onDrop) // ← bubble phase; must become capture +}, +beforeUnmount() { + window.removeEventListener('dragenter', this.onDragEnter) + window.removeEventListener('dragleave', this.onDragLeave) + window.removeEventListener('dragover', this.onDragOver) + window.removeEventListener('drop', this.onDrop) // ← must match with true +} +``` + +From frontend/src/views/FileManagerView.vue defineExpose (lines 190-196): +```js +// These ARE correct — all methods are exposed. The problem is App.vue never reaches this instance. +defineExpose({ + focusSearch: () => browserRef.value?.focusSearch?.(), + triggerUpload: () => browserRef.value?.triggerUpload?.(), + startNewFolder: () => browserRef.value?.startNewFolder?.(), + clearSearch: () => browserRef.value?.clearSearch?.(), + handleOsDrop: (files) => onFilesSelected({ files, autoClassify: true }), +}) +``` + +From frontend/src/__tests__/keyboard.test.js (existing structure): +Uses mountFileManager() helper, vi.mock('../api/client.js', ...), vi.mock('../stores/auth.js', ...), +vi.mock('../stores/topics.js', ...), setActivePinia(createPinia()), createRouter+createMemoryHistory. +
+
+ + + + + Task 1: Sidebar shimmer rows (TreeItem.vue) and search-at-root (StorageBrowser.vue) + + frontend/src/components/ui/TreeItem.vue + frontend/src/components/storage/StorageBrowser.vue + + + TreeItem.vue — replace the v-if="loading" div (lines 48-52) with a shimmer block. The replacement wraps three shimmer rows in a single container div. Apply the indent :style on the container (same binding the removed div had: `{ paddingLeft: \`\${(depth + 1) * 12 + 8}px\` }`). The container also gets `class="py-1 space-y-1"`. Each of the three inner rows uses `class="flex items-center gap-2 py-1"` and contains two children: + - Icon placeholder: `class="w-4 h-4 bg-gray-100 rounded animate-pulse shrink-0"` + - Text placeholder: `class="h-3 bg-gray-100 rounded animate-pulse"` with `:style="{ width: (50 + n * 15) + 'px' }"` + Use `v-for="n in 3"` with `:key="\`sk-t-\${n}\`"` on the inner row div. + Do not change any other branch (v-else-if loadError, v-else-if children.length===0, slot children) or any script section. + + StorageBrowser.vue — change line 287 only. Change: + `const showSearch = computed(() => props.mode === 'local' && props.breadcrumb.length > 0)` + to: + `const showSearch = computed(() => props.mode === 'local' || props.mode === 'cloud')` + No template changes needed — SearchBar and SortControls already share v-if="showSearch". + + + cd /Users/nik/Documents/Progamming/document_scanner/frontend && grep -c "animate-pulse" src/components/ui/TreeItem.vue && grep "showSearch" src/components/storage/StorageBrowser.vue | grep "cloud" + + + - `grep -c "animate-pulse" src/components/ui/TreeItem.vue` returns at least 2 + - `grep -c "Loading" src/components/ui/TreeItem.vue` returns 0 + - `grep "showSearch" src/components/storage/StorageBrowser.vue` contains `props.mode === 'cloud'` + + + + + Task 2: Admin sidebar bleed and keyboard instance resolution (App.vue) + frontend/src/App.vue + + Two root causes, one file. Apply both changes together. + + CHANGE A — Admin sidebar bleed (Gap 3): + Insert a v-else-if branch in the template between the auth branch and the user-layout div. The new branch condition is `route.matched.some(r => r.meta.requiresAdmin)`. When true it renders only `` — no AppSidebar, no main wrapper. The complete corrected template root (inside the component root, excluding ToastContainer and OsDragOverlay which stay unchanged): + + 1. `` + 2. `` + 3. `
` ... AppSidebar + main + router-view (no ref attribute) ... `
` + + Note: the router-view in branch 3 must NOT carry `ref="routeViewRef"` — refs on router-view resolve to the RouterView proxy (same root cause as Gap 4). Remove the ref attribute. + + CHANGE B — Keyboard instance resolution (Gap 4, also fixes tests 12 and 13): + The `routeViewRef` ref and its usage must be replaced with a direct instance lookup: + 1. Add `useRouter` to the `vue-router` import: `import { useRoute, useRouter } from 'vue-router'` + 2. Add `const router = useRouter()` after `const route = useRoute()` + 3. Add helper: `function getFileManagerInstance() { return router.currentRoute.value.matched.find(r => r.instances?.default)?.instances?.default ?? null }` + 4. Remove `const routeViewRef = ref(null)` — no longer used + 5. Remove `ref` from the `ref` import if it is now unused (check — ref was only used for routeViewRef) + 6. Replace all `routeViewRef.value?.X?.()` calls in onKeydown with `getFileManagerInstance()?.X?.()` + 7. Replace `routeViewRef.value?.handleOsDrop?.(files)` in onOsFilesDropped with `getFileManagerInstance()?.handleOsDrop?.(files)` + + After both changes, `ref` from vue should be removed from the import line if nothing else uses it (check first — if ToastContainer or OsDragOverlay use a local ref, keep it; otherwise remove to avoid lint warnings). +
+ + cd /Users/nik/Documents/Progamming/document_scanner/frontend && grep "routeViewRef" src/App.vue; echo "exit:$?"; grep "instances.default" src/App.vue; grep "requiresAdmin" src/App.vue + + + - `grep "routeViewRef" src/App.vue` returns no output (fully removed) + - `grep "instances.default" src/App.vue` returns the getFileManagerInstance() line + - `grep "requiresAdmin" src/App.vue` returns the v-else-if template branch + - `grep "useRouter" src/App.vue` appears in import and instantiation + +
+ + + Task 3: Escape modifier (SearchBar.vue) and capture-phase drop (OsDragOverlay.vue) + + frontend/src/components/documents/SearchBar.vue + frontend/src/components/layout/OsDragOverlay.vue + + + SearchBar.vue — one character change on line 11. Add `.prevent.stop` modifiers to `@keydown.escape`: + Before: `@keydown.escape="emit('update:modelValue', '')"` + After: `@keydown.escape.prevent.stop="emit('update:modelValue', '')"` + `.prevent` stops the browser's native clear+blur behavior on type="search" inputs. `.stop` stops bubbling to App.vue's global keydown handler (which would call clearSearch() a second time). No other changes. + + OsDragOverlay.vue — two lines change in the Options API lifecycle hooks: + In mounted(): change `window.addEventListener('drop', this.onDrop)` to `window.addEventListener('drop', this.onDrop, true)` + In beforeUnmount(): change `window.removeEventListener('drop', this.onDrop)` to `window.removeEventListener('drop', this.onDrop, true)` + + The third argument `true` registers the listener in capture phase, meaning it runs before any bubble-phase handlers on child elements (including `@drop.prevent` on folder rows in StorageBrowser.vue). The removeEventListener MUST also pass `true` — EventTarget tracks bubble-phase and capture-phase registrations separately, so without `true` the cleanup call would fail silently and the listener would leak. + + Do not change dragenter, dragleave, or dragover listeners — those remain in bubble phase and work correctly. + + + cd /Users/nik/Documents/Progamming/document_scanner/frontend && grep "keydown.escape" src/components/documents/SearchBar.vue && grep -n "addEventListener.*drop\|removeEventListener.*drop" src/components/layout/OsDragOverlay.vue + + + - `grep "keydown.escape" src/components/documents/SearchBar.vue` shows `.prevent.stop` in the modifier chain + - `grep "addEventListener.*drop" src/components/layout/OsDragOverlay.vue` shows `true` as third argument + - `grep "removeEventListener.*drop" src/components/layout/OsDragOverlay.vue` shows `true` as third argument + + + + + Task 4: Regression tests for all 6 gaps + + frontend/src/__tests__/keyboard.test.js + frontend/src/components/ui/__tests__/TreeItem.test.js + frontend/src/components/storage/__tests__/StorageBrowser.showSearch.test.js + + + TreeItem shimmer: + - When loading=true and expanded=true → rendered HTML contains elements with class "animate-pulse" + - When loading=true and expanded=true → text "Loading" does not appear in rendered HTML + + StorageBrowser showSearch: + - mode='local', breadcrumb=[] → showSearch is true (root-level local, previously false) + - mode='local', breadcrumb=[{name:'Folder'}] → showSearch is true (non-root local) + - mode='cloud', breadcrumb=[] → showSearch is true (cloud root, previously always false) + - mode='shared' → showSearch is false + + App.vue keyboard dispatch: + - matched.find(r => r.instances?.default)?.instances?.default on a mounted FileManagerView router returns an object with focusSearch defined + + + keyboard.test.js — append a new describe block at the end of the existing file (do not modify or move existing describes): + + "Gap 4: getFileManagerInstance resolves to actual component, not RouterView proxy" — using the existing mountFileManager() helper and makeRouter(), after mounting FileManagerView and flushing promises, access `router.currentRoute.value.matched.find(r => r.instances?.default)?.instances?.default` and assert that it is not null and has a `focusSearch` property. This proves the resolution mechanism the refactored App.vue uses is correct. Import `useRouter` from vue-router at the top if not already imported — check existing imports first. + + TreeItem.test.js — create at `frontend/src/components/ui/__tests__/TreeItem.test.js`: + - Import: `describe, it, expect, vi` from vitest; `mount, flushPromises` from @vue/test-utils; TreeItem from the component + - Mock AppIcon: `vi.mock('../AppIcon.vue', () => ({ default: { template: '' } }))` + - Helper: `mountExpanded(overrides = {})` — mounts TreeItem with `label="Test"`, `loadChildren: vi.fn().mockResolvedValue([])`, `expandable: true` and spreads overrides. After mount, call `w.vm.toggleExpand()` via `w.vm.$.setupState.toggleExpand()` (or trigger the expand button click) and flush promises to reach expanded state with children loaded. + - For the loading=true test: mount with a loadChildren that returns a promise that never resolves (`new Promise(() => {})`). Click the expand button to trigger load. Before flushing, assert the HTML. The loading ref will be true while the promise is pending. + - describe "Gap 1: sidebar shimmer rows": two tests as per behavior block above. + - describe "Gap 1 regression: non-loading branches unchanged": one test asserting that with loadChildren resolving to [] and expanded, the "Empty" text appears (sibling v-else-if branch guard). + + StorageBrowser.showSearch.test.js — create at `frontend/src/components/storage/__tests__/StorageBrowser.showSearch.test.js`: + - Heavy stub setup: all child components that StorageBrowser imports must be stubbed (SearchBar, SortControls, DocumentCard, FolderRow, EmptyState, AppIcon, BreadcrumbBar, DropZone, etc.) — use `stubs: { SearchBar: true, SortControls: true, ... }` in global mount options or individual vi.mock calls. + - Mock all API calls used on mount (listDocuments, listFolders, etc.) via vi.mock('../../../api/client.js', ...). + - After mount with given props, access `w.vm.showSearch` directly as a computed. + - Props for mount: at minimum `mode`, `breadcrumb`, `documents: []`, `folders: []`, `topicColorFn: () => '#000'`, `loading: false`. + - Four it() blocks as per behavior block above. + - Wrap in `describe("Gap 2: showSearch visible at root for local and cloud modes", ...)`. + + All new tests run as part of `npm run test -- --run` without additional flags. + + + cd /Users/nik/Documents/Progamming/document_scanner/frontend && npm run test -- --reporter=verbose --run 2>&1 | grep -E "(PASS|FAIL|SKIP| ✓ | × | ✗ )" | tail -50 + + + - All new describe blocks appear in output with passing test indicators + - `npm run test -- --run` exits 0 with zero failures + - `grep -c "animate-pulse" src/components/ui/__tests__/TreeItem.test.js` returns at least 1 + - `grep -c "showSearch" src/components/storage/__tests__/StorageBrowser.showSearch.test.js` returns at least 4 + + + +
+ + +## Trust Boundaries + +| Boundary | Description | +|----------|-------------| +| OS file drag → window drop (capture) | Files arrive via browser DataTransfer API — browser-enforced; no network boundary crossed; payload handled only client-side before going through existing authenticated upload flow | +| Admin route layout selection | Template branch selection is display-only — backend enforces admin access via get_current_admin dep on every admin endpoint; changing template rendering creates no auth regression | + +## STRIDE Threat Register + +| Threat ID | Category | Component | Disposition | Mitigation Plan | +|-----------|----------|-----------|-------------|-----------------| +| T-10gc-01 | Tampering | OsDragOverlay capture-phase drop handler | accept | Handler reads only e.dataTransfer.files (browser-controlled), resets overlay state, emits to parent — no direct server interaction; upload goes through existing authenticated API path unchanged | +| T-10gc-02 | Spoofing | router.currentRoute.value.matched.find().instances.default | accept | Read-only Vue internals lookup; no user-supplied data flows through this path; cannot be spoofed via URL manipulation — Vue populates instances after component mount, not from route params | +| T-10gc-03 | Elevation of Privilege | App.vue v-else-if admin branch | accept | Branch adds a missing layout guard (removes AppSidebar for admin); it does not grant or deny route access — navigation guard in router/index.js is unchanged and continues to enforce requiresAdmin check | +| T-10gc-SC | Tampering | npm/pip/cargo installs | accept | No new packages installed — all fixes are template/script edits to existing files | + + + +Manual UAT re-run checklist (all must pass before marking complete): + +Gap 1 — Sidebar shimmer: Expand a cloud provider tree item in the sidebar while data loads. Animated shimmer rows appear; "Loading…" text is absent. + +Gap 2 — Search at root: Navigate to / (file manager root, no folder entered). Search bar and sort controls are visible in the content area header. + +Gap 3 — Admin sidebar: Navigate to /admin/users in a logged-in admin session. Only the AdminLayout and AdminSidebar render — AppSidebar (user nav) is absent. + +Gap 4 — Keyboard shortcuts: With the file manager at root, press '/'. Search bar receives cursor focus. Press 'U'. File picker dialog opens. Press 'N'. New folder inline input appears. + +Gap 5 — Escape behavior: Type text into the search bar. Press Escape. Field clears. Cursor remains in the field. Type again immediately — new characters appear (no re-click required). + +Gap 6 — OS drag-drop: Drag a file from Finder/Explorer over the browser window. Overlay appears. Release the file. Upload begins (progress visible or toast appears). + +Automated gate: +`cd frontend && npm run test -- --run` — exits 0, zero failures, no skipped tests regressed. + + + +- All 6 UAT gaps confirmed closed by manual re-run of the 6 scenarios above +- `npm run test -- --run` exits 0 with zero failures across the full suite (baseline: 211 passing) +- Five production files modified with surgical changes only — no refactors, no feature additions +- Three new test files committed with passing tests covering each gap +- `grep -c "Loading" frontend/src/components/ui/TreeItem.vue` returns 0 +- `grep "showSearch" frontend/src/components/storage/StorageBrowser.vue` matches the `|| props.mode === 'cloud'` form +- `grep "routeViewRef" frontend/src/App.vue` returns empty +- `grep "requiresAdmin" frontend/src/App.vue` returns the v-else-if template branch line +- `grep "addEventListener.*drop.*true" frontend/src/components/layout/OsDragOverlay.vue` returns a match +- `grep "removeEventListener.*drop.*true" frontend/src/components/layout/OsDragOverlay.vue` returns a match +- `grep "prevent.stop" frontend/src/components/documents/SearchBar.vue` returns the escape handler line + + + +Create `/Users/nik/Documents/Progamming/document_scanner/.planning/phases/10-ux-interaction/10-13-SUMMARY.md` when done. + diff --git a/.planning/phases/10-ux-interaction/10-13-SUMMARY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-13-SUMMARY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-13-SUMMARY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-13-SUMMARY.md diff --git a/.planning/phases/10-ux-interaction/10-CONTEXT.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-CONTEXT.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-CONTEXT.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-CONTEXT.md diff --git a/.planning/phases/10-ux-interaction/10-DISCUSSION-LOG.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-DISCUSSION-LOG.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-DISCUSSION-LOG.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-DISCUSSION-LOG.md diff --git a/.planning/phases/10-ux-interaction/10-PATTERNS.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-PATTERNS.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-PATTERNS.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-PATTERNS.md diff --git a/.planning/phases/10-ux-interaction/10-RESEARCH.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-RESEARCH.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-RESEARCH.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-RESEARCH.md diff --git a/.planning/phases/10-ux-interaction/10-REVIEW.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-REVIEW.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-REVIEW.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-REVIEW.md diff --git a/.planning/phases/10-ux-interaction/10-SECURITY.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-SECURITY.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-SECURITY.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-SECURITY.md diff --git a/.planning/phases/10-ux-interaction/10-UAT.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-UAT.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-UAT.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-UAT.md diff --git a/.planning/phases/10-ux-interaction/10-VALIDATION.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-VALIDATION.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-VALIDATION.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-VALIDATION.md diff --git a/.planning/phases/10-ux-interaction/10-VERIFICATION.md b/.planning/milestones/v0.2-phases/10-ux-interaction/10-VERIFICATION.md similarity index 100% rename from .planning/phases/10-ux-interaction/10-VERIFICATION.md rename to .planning/milestones/v0.2-phases/10-ux-interaction/10-VERIFICATION.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-01-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-01-PLAN.md new file mode 100644 index 0000000..cb10dac --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-01-PLAN.md @@ -0,0 +1,42 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 1 +type: execute +wave: 0 +depends_on: [10-complete] +requirements: [PERF-02] +files_modified: + - frontend/vite.config.js + - .planning/phases/11-visual-design-responsive-layout-cleanup/11-RESEARCH.md + - .planning/perf/phase11-baseline.html + - .planning/perf/phase11-baseline-summary.md +autonomous: true +--- + +# Plan 11-01 — Bundle Baseline & UI Audit + +## Objective + +Capture the Phase 11 pre-optimization bundle baseline before any lazy-loading or visual cleanup begins, then record a targeted audit of the visual/responsive issues Phase 11 will address. + +## Tasks + +1. Wire existing `rollup-plugin-visualizer` into `frontend/vite.config.js` behind an opt-in environment flag such as `ANALYZE=true`. The dependency already exists in `frontend/package.json`. +2. Run a production build with analysis enabled and write the baseline report to `.planning/perf/phase11-baseline.html`. +3. Add `.planning/perf/phase11-baseline-summary.md` with bundle size, largest chunks, route/component observations, and the exact command used. +4. Update `11-RESEARCH.md` if execution discovers facts that differ from the refresh research. +5. Audit the frontend for Phase 11 targets: + - synchronous non-critical route imports + - responsive sidebar/admin sidebar gaps + - tables or grids that overflow below `sm`/`md` + - modal overflow below 640px + - inconsistent form, hover, focus, active, spacing, and typography patterns + - unreferenced files and imports + +## Acceptance Criteria + +- Baseline bundle report exists before any Phase 11 optimization commits. +- `vite.config.js` does not generate analyzer output unless explicitly requested. +- `11-RESEARCH.md` remains accurate after the baseline build. +- Audit notes are concrete enough that plans 11-02 through 11-06 can execute without rediscovering scope. +- `cd frontend && npm run build` succeeds with and without analysis enabled. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-01-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-01-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-01-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-01-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-02-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-02-PLAN.md new file mode 100644 index 0000000..fd8ca43 --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-02-PLAN.md @@ -0,0 +1,43 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 2 +type: execute +wave: 1 +depends_on: [11-01] +requirements: [PERF-03] +files_modified: + - frontend/src/router/index.js + - frontend/src/router/__tests__/router.guard.test.js +autonomous: true +--- + +# Plan 11-02 — Lazy-Load Non-Critical Routes + +## Objective + +Satisfy PERF-03 by lazy-loading every route component that is not needed for the initial render, while preserving auth/admin guard behavior. + +## Tasks + +1. Keep `FileManagerView` synchronous for `/` as the critical first authenticated surface unless the baseline report shows a strong reason to split it. Document this in `router/index.js` near the import. +2. Replace synchronous imports in `frontend/src/router/index.js` for non-initial routes: + - `TopicsView` + - `DocumentView` + - `SettingsView` + - `CloudStorageView` + - `CloudFolderView` +3. Keep `/folders/:folderId` on the same `FileManagerView` component for behavior parity with `/`; it is already in the initial chunk because `/` uses the same component. +4. Preserve existing lazy auth/admin/shared route imports. +5. Extend router tests so guard behavior is verified with lazy route components: + - non-admin cannot enter `/admin/*` + - admin redirects away from non-admin routes + - refresh-before-guard still runs when access token is absent + - `/topics`, `/document/:id`, `/settings`, `/cloud`, and `/cloud/:provider/:folderId` still resolve +6. Build once and confirm route chunks are emitted. + +## Acceptance Criteria + +- `rg "import .*View" frontend/src/router/index.js` only returns `FileManagerView` unless a new initial-render route is explicitly justified. +- Admin child routes remain lazy-loaded. +- Router guard tests pass. +- `cd frontend && npm run build` succeeds and emits split route chunks. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-02-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-02-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-02-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-02-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-03-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-03-PLAN.md new file mode 100644 index 0000000..71c128a --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-03-PLAN.md @@ -0,0 +1,52 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 3 +type: execute +wave: 2 +depends_on: [11-02] +requirements: [RESP-01, RESP-02, RESP-03, RESP-05] +files_modified: + - frontend/src/App.vue + - frontend/src/layouts/AdminLayout.vue + - frontend/src/components/layout/AppSidebar.vue + - frontend/src/components/admin/AdminSidebar.vue + - frontend/src/components/storage/StorageBrowser.vue + - frontend/src/__tests__/keyboard.test.js + - frontend/src/components/storage/__tests__/StorageBrowser.skeleton.test.js +autonomous: true +--- + +# Plan 11-03 — Responsive Shells & Storage Rows + +## Objective + +Make both user and admin layouts usable below `lg`, and make storage rows fit smaller viewports without losing core actions. + +## Tasks + +1. Use layout-local drawer refs, not a new Pinia store: + - `App.vue` owns user drawer state. + - `AdminLayout.vue` owns admin drawer state. + - Watch route changes in each layout root and close the drawer after navigation. + - Do not put drawer state in `AppSidebar.vue` or `AdminSidebar.vue`. +2. Add a mobile-only header with a hamburger button for the user layout. +3. Hide `AppSidebar` below `lg`; open it in a slide-in overlay drawer with backdrop tap, route-change close, and `translate-x-0` / `-translate-x-full` transition. +4. Apply the same responsive shell behavior to `AdminLayout` and `AdminSidebar`. +5. Update `StorageBrowser` row/grid classes so: + - Size column hides below `md` + - Modified column hides below `sm` + - icon, name, and actions remain visible + - grid templates do not reserve hidden column widths on mobile +6. Ensure inline icon action buttons have at least `36px` touch targets below `md`. +7. Add or update tests for drawer open/close, route-change close, admin drawer behavior, responsive column classes, and touch target classes. +8. Verify with browser screenshots or Playwright at 375px, 768px, 1024px, and desktop width. + +## Acceptance Criteria + +- User sidebar is hidden below 1024px and accessible through a hamburger drawer. +- Admin sidebar has matching mobile behavior. +- Drawer closes on backdrop tap and navigation tap. +- Storage rows satisfy RESP-02 without horizontal overflow at 375px. +- Icon actions satisfy RESP-03. +- Drawer state is owned only by `App.vue` and `AdminLayout.vue`. +- Frontend tests and build pass. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-03-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-03-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-03-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-03-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-04-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-04-PLAN.md new file mode 100644 index 0000000..4367a19 --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-04-PLAN.md @@ -0,0 +1,40 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 4 +type: execute +wave: 3 +depends_on: [11-03] +requirements: [VISUAL-02, RESP-04] +files_modified: + - frontend/tailwind.config.js + - frontend/src/components/**/*.vue + - frontend/src/views/**/*.vue +autonomous: true +--- + +# Plan 11-04 — Forms Baseline & Mobile-Safe Modals + +## Objective + +Normalize form controls through `@tailwindcss/forms` and make every modal scroll safely on mobile viewports. + +## Tasks + +1. Confirm `@tailwindcss/forms` remains installed and active in `tailwind.config.js`; it is already wired today, so this should be a verification step unless execution finds drift. +2. Audit inputs, selects, textareas, checkboxes, and radio buttons for conflicting per-component browser-reset styles. +3. Normalize form classes to the smallest consistent Tailwind pattern already used by the app. +4. Update modal shells so content below 640px is scrollable and never exceeds viewport height: + - `ShareModal.vue`: centered panel gets mobile `max-h` and `overflow-y-auto`. + - `CloudCredentialModal.vue`: tall WebDAV/Nextcloud form gets mobile `max-h` and `overflow-y-auto`. + - `FolderDeleteModal.vue`: adopt the same mobile-safe panel pattern. + - `DocumentPreviewModal.vue`: preserve full-screen preview but verify header/content sizing at narrow widths. + - any auth/account confirmation modal-like surfaces found in the audit +5. Add focused tests or DOM assertions for mobile-safe modal classes and form baseline coverage. + +## Acceptance Criteria + +- Forms plugin is active and relied on consistently. +- No modal content overflows a 375x667 viewport. +- No modal text or action row is clipped below 640px. +- The desktop modal appearance remains behaviorally unchanged. +- `npm run test -- --run` and `npm run build` pass. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-04-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-04-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-04-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-04-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-05-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-05-PLAN.md new file mode 100644 index 0000000..dfaa95f --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-05-PLAN.md @@ -0,0 +1,46 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 5 +type: execute +wave: 4 +depends_on: [11-04] +requirements: [VISUAL-01, VISUAL-03, VISUAL-04] +files_modified: + - frontend/src/components/**/*.vue + - frontend/src/views/**/*.vue +autonomous: true +--- + +# Plan 11-05 — Visual Consistency Pass + +## Objective + +Make spacing, typography, hover, focus-visible, and active states consistent across the frontend without introducing a component-library rewrite. + +## Tasks + +1. Preserve legitimate data-driven inline styles: + - topic color swatches + - quota/progress widths + - Teleport dropdown coordinates + - tree indentation +2. Remove arbitrary spacing and decorative inline styles unless they are data-driven layout values with no Tailwind equivalent. +3. Normalize typography to this app scale: + - page title: `text-2xl font-semibold` + - section title: `text-lg font-semibold` + - panel/table heading: `text-sm font-semibold` + - body: `text-sm` + - caption/metadata: `text-xs` +4. Replace generic `focus:ring-*` only patterns on interactive elements with this keyboard focus convention: `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1`. +5. Ensure buttons, links, card rows, table rows, menu items, and icon actions have coherent hover and active states. +6. Avoid broad palette changes; preserve the current DocuVault identity while removing one-off visual drift. +7. Add focused tests or static checks for the agreed invariants where practical. + +## Acceptance Criteria + +- No unnecessary `px-[...]`, margin `style=`, or one-off typography overrides remain. +- Interactive elements have hover plus keyboard-visible focus states. +- Typography reads as one app scale, not per-component choices. +- Data-driven inline styles remain where they carry runtime values. +- Visual changes are behavior-preserving. +- Frontend tests and build pass. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-05-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-05-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-05-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-05-SUMMARY.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-06-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-06-PLAN.md new file mode 100644 index 0000000..3f0bc29 --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-06-PLAN.md @@ -0,0 +1,45 @@ +--- +phase: 11-visual-design-responsive-layout-cleanup +plan: 6 +type: execute +wave: 5 +depends_on: [11-05] +requirements: [CODE-07, PERF-02] +files_modified: + - frontend/src/**/* + - .planning/perf/phase11-final.html + - .planning/perf/phase11-final-summary.md + - .planning/phases/11-visual-design-responsive-layout-cleanup/11-VERIFICATION.md +autonomous: true +--- + +# Plan 11-06 — Dead-Code Cleanup & Final Measurement + +## Objective + +Delete unreferenced frontend code and capture the final bundle report after all Phase 11 optimizations are complete. + +## Tasks + +1. Run dead-code searches for unreferenced components, stores, helpers, imports, and old route views. +2. Explicitly classify these known suspects before deleting or retaining: + - `frontend/src/views/AccountView.vue` (`/account` currently redirects to `/settings`) + - `frontend/src/components/admin/__tests__/AdminAiConfigTab.test.js` + - `frontend/src/components/admin/__tests__/AdminQuotasTab.test.js` + - `frontend/src/components/admin/__tests__/AdminUsersTab.test.js` +3. Confirm `HomeView.vue`, `FolderView.vue`, and `AdminView.vue` remain absent. +4. Delete files with no active route and no active import in the same commit as their references are removed. +5. Remove unused imports and stale tests that target deleted files; keep behavior tests that still protect live surfaces. +6. Run the final analyzer build and write `.planning/perf/phase11-final.html`. +7. Add `.planning/perf/phase11-final-summary.md` comparing baseline vs final bundle size, chunk count, and largest chunks. +8. Produce `11-VERIFICATION.md` mapping every Phase 11 requirement to code/test/build evidence. + +## Acceptance Criteria + +- CODE-07 is satisfied: no dead files, unused route components, unused stores, or unused imports remain. +- Known suspects are each documented as deleted or intentionally retained. +- Final bundle report and summary are committed under `.planning/perf/`. +- Baseline and final reports are both present. +- `cd frontend && npm run test -- --run` passes. +- `cd frontend && npm run build` passes. +- Phase 11 verification maps VISUAL-01..04, RESP-01..05, CODE-07, PERF-02, and PERF-03 to concrete evidence. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-06-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-06-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-06-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-06-SUMMARY.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-07-PLAN.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-07-PLAN.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-07-PLAN.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-07-PLAN.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-07-SUMMARY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-07-SUMMARY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-07-SUMMARY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-07-SUMMARY.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md similarity index 93% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md index 6cbf6b6..03dc6fc 100644 --- a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-CONTEXT.md @@ -39,7 +39,7 @@ This phase is **purely frontend** — no backend changes, no new features. ### Performance (PERF-02, PERF-03) - **D-09:** Bundle baseline captured in Plan 11-01 (before any changes). Final measurement in Plan 11-06 (after all changes). Both reports committed to `.planning/perf/`. -- **D-10:** Login/Register route (`/login`, `/register`) may stay synchronous if needed for first-paint — document the rationale in the router. All other authenticated routes (Topics, Document detail, Settings, Cloud, admin subtree) must be lazy. +- **D-10:** `FileManagerView` may stay synchronous for `/` as the critical first authenticated surface — document the rationale in the router. Auth routes and admin routes are already lazy-loaded. All other authenticated routes (Topics, Document detail, Settings, Cloud) must be lazy. ### Claude's Discretion @@ -75,7 +75,7 @@ This phase is **purely frontend** — no backend changes, no new features. - `frontend/src/components/admin/AdminSidebar.vue` — admin sidebar; same responsive behavior - `frontend/src/components/storage/StorageBrowser.vue` — responsive column hiding: Size below `md`, Modified below `sm`; touch targets (RESP-03) - `frontend/src/router/index.js` — add `() => import(...)` lazy loading for non-initial routes (PERF-03) -- `frontend/tailwind.config.js` — add `@tailwindcss/forms` plugin (VISUAL-02) +- `frontend/tailwind.config.js` — verify `@tailwindcss/forms` plugin remains active (VISUAL-02) - `frontend/vite.config.js` — add `rollup-plugin-visualizer` behind `ANALYZE=true` env flag (PERF-02) ### Phase 10 Patterns (carry forward) @@ -102,7 +102,7 @@ This phase is **purely frontend** — no backend changes, no new features. - `App.vue` — user layout root; hamburger button + sidebar drawer mount here. Phase 10 already added ``-based toast container and drag overlay here. - `AdminLayout.vue` — admin layout root; separate hamburger button needed for admin nav drawer (RESP-05); same structural pattern as `App.vue` - `frontend/src/router/index.js` — lazy-load additions happen here; preserve all existing `meta: { requiresAuth, requiresAdmin }` guards -- `frontend/tailwind.config.js` — add `@tailwindcss/forms` plugin; do not break existing utility classes +- `frontend/tailwind.config.js` — `@tailwindcss/forms` is already active; do not break existing utility classes ### PERF-02 Bundle Workflow - Plan 11-01 adds `rollup-plugin-visualizer` behind `ANALYZE=true` and captures baseline in `.planning/perf/phase11-baseline.html` @@ -118,7 +118,7 @@ This phase is **purely frontend** — no backend changes, no new features. - Backdrop for drawer: semi-transparent overlay, tap to close. Use `` consistent with existing overlay pattern. - Touch target minimum: `min-w-[36px] min-h-[36px]` or equivalent padding on icon action buttons below `md`. - Modal scroll: `max-h-[90vh] overflow-y-auto` pattern on modal content container for viewports below 640px. -- `@tailwindcss/forms` strategy: install plugin, audit all form elements for conflicting per-component reset styles, normalize to smallest consistent Tailwind class set already used in the app. +- `@tailwindcss/forms` strategy: verify plugin remains active, audit all form elements for conflicting per-component reset styles, normalize to smallest consistent Tailwind class set already used in the app. diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-DISCUSSION-LOG.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-DISCUSSION-LOG.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-DISCUSSION-LOG.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-DISCUSSION-LOG.md diff --git a/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-RESEARCH.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-RESEARCH.md new file mode 100644 index 0000000..97337f8 --- /dev/null +++ b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-RESEARCH.md @@ -0,0 +1,94 @@ +# Phase 11 Research Refresh — Visual Design, Responsive Layout & Cleanup + +**Researched:** 2026-06-16 +**Inputs:** Phase 11 context, roadmap, requirements, pitfall notes, live frontend code. + +## Executive Summary + +The six-plan Phase 11 sequence is structurally sound: measure first, lazy-load routes, fix responsive shells, normalize forms/modals, do the visual consistency pass, then delete dead code and measure again. The second review found several places where the plans needed sharper implementation constraints, especially because `11-CONTEXT.md` contains locked decisions that were not fully reflected in the first review. + +## Current Code Findings + +### Performance + +- `frontend/package.json` already includes `rollup-plugin-visualizer@^7.0.1`. +- `frontend/vite.config.js` currently has only `vue()` in `plugins`; analyzer wiring still needs to be added behind an opt-in flag. +- `frontend/src/router/index.js` still synchronously imports: + - `FileManagerView` + - `TopicsView` + - `DocumentView` + - `SettingsView` + - `CloudFolderView` + - `CloudStorageView` +- Auth routes, admin layout, admin child views, and `SharedView` are already lazy-loaded. +- Recommendation: keep `FileManagerView` synchronous only for `/` as the critical first authenticated surface. Lazy-load `TopicsView`, `DocumentView`, `SettingsView`, `CloudStorageView`, and `CloudFolderView`. Reuse the synchronous `FileManagerView` for `/folders/:folderId` unless the bundle baseline proves it should be split later. + +### Responsive Shells + +- `App.vue` renders a desktop-only `flex h-screen overflow-hidden` shell with permanent `AppSidebar`. +- `AdminLayout.vue` mirrors that desktop-only shell with permanent `AdminSidebar`. +- `AppSidebar.vue` and `AdminSidebar.vue` are presentational enough to stay drawer-agnostic. +- Recommendation: use layout-local refs in `App.vue` and `AdminLayout.vue`, not a new Pinia store. Nav link close behavior can be handled by watching route changes in each layout root; no child component needs global drawer state. + +### Storage Rows + +- `StorageBrowser.vue` already hides Size below `md` and Modified below `sm` via `hidden md:block` and `hidden sm:block`. +- The grid template remains fixed at `grid-cols-[2rem_1fr_6rem_8rem_6rem]`, so responsive column sizing still needs explicit adjustment to avoid empty tracks and mobile overflow. +- Existing row action buttons use `p-1.5`, which may not guarantee 36x36 touch targets below `md`. + +### Forms + +- `@tailwindcss/forms` is already installed and active in `frontend/tailwind.config.js`. +- Many controls still carry repeated full border/focus class stacks. Plan 11-04 should normalize those without introducing a new component library. + +### Modals + +Mobile overflow risk is concrete: + +- `ShareModal.vue`: fixed overlay, centered panel, `rounded-2xl`, no `max-h` or `overflow-y-auto`. +- `CloudCredentialModal.vue`: fixed overlay, centered panel, `max-w-md p-6`, no `max-h` or `overflow-y-auto`; form can become tall with advanced Nextcloud fields. +- `FolderDeleteModal.vue`: smaller but should still receive the shared mobile-safe panel pattern. +- `DocumentPreviewModal.vue`: full-screen preview is structurally different; it should preserve full-screen behavior and ensure header/content do not overflow on narrow screens. + +Recommended modal shell pattern: overlay uses `p-4 sm:p-6`; panel uses `max-h-[calc(100vh-2rem)] overflow-y-auto` below `sm`, with desktop styling preserved. + +### Visual Consistency + +- Current frontend heavily uses `focus:ring-2` but rarely `focus-visible:`. +- `rounded-xl` and `rounded-2xl` appear on several ordinary panels/modals even though AGENTS.md prefers cards at 8px radius unless the design system requires otherwise. +- There are data-driven inline styles that should remain: + - topic color swatches + - quota/progress bar widths + - Teleport dropdown coordinates + - tree indentation +- There are skeleton width styles such as `:style="{ width: (50 + n * 15) + 'px' }"` that are decorative and can be converted to static Tailwind widths during the visual pass. + +Recommended convention: + +- Page title: `text-2xl font-semibold` +- Section title: `text-lg font-semibold` +- Panel/table heading: `text-sm font-semibold` +- Body: `text-sm` +- Caption/metadata: `text-xs` +- Focus ring: `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1` + +### Dead Code Signals + +- `HomeView.vue` and `FolderView.vue` remain absent, satisfying AGENTS.md. +- Legacy admin-tab test names still exist under `frontend/src/components/admin/__tests__/`: + - `AdminAiConfigTab.test.js` + - `AdminQuotasTab.test.js` + - `AdminUsersTab.test.js` +- These tests may still cover current components via renamed imports or may be stale; Plan 11-06 should explicitly classify them. +- `AccountView.vue` exists but `/account` redirects to `/settings`. It may be dead unless imported outside the router. Plan 11-06 should confirm before deleting. + +## Review Verdict + +The plan set remains valid after review, but it should be refined with: + +- a documented layout-local drawer-state decision +- exact route lazy-loading scope +- exact modal overflow targets +- a locked focus-ring and typography convention +- explicit dead-code suspects for Plan 11-06 + diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-REVIEW.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-REVIEW.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-REVIEW.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-REVIEW.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-SECURITY.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-SECURITY.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-SECURITY.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-SECURITY.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-UAT.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-UAT.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-UAT.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-UAT.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-VALIDATION.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-VALIDATION.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-VALIDATION.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-VALIDATION.md diff --git a/.planning/phases/11-visual-design-responsive-layout-cleanup/11-VERIFICATION.md b/.planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-VERIFICATION.md similarity index 100% rename from .planning/phases/11-visual-design-responsive-layout-cleanup/11-VERIFICATION.md rename to .planning/milestones/v0.2-phases/11-visual-design-responsive-layout-cleanup/11-VERIFICATION.md