Packages
Projects module for PhoenixKit — projects, reusable tasks, assignments, and dependencies.
Current section
Files
Jump to
Current section
Files
phoenix_kit_projects
CHANGELOG.md
CHANGELOG.md
# Changelog
## 0.2.0
### Added
- **Multilang content** — project name/description, task title/description, and
assignment description are now translatable via core's Languages module.
Forms auto-render `<.multilang_tabs>` when 2+ languages are enabled; primary
values stay in their columns, overrides live in a `translations JSONB`.
- **Task groups view** — task templates can be grouped by dependency tree in the
task-library UI, with visual `→ X` badges showing outgoing edges.
- **Drag-and-drop reorder** — projects, templates, and tasks can be reordered
via sortable tables with `phx-reorder` events. Dedup logic guarantees
last-write-wins on duplicate UUIDs.
- **Closure-pull cascade** — adding a task to a project can optionally pull in
its entire upstream dependency closure with automatic `Dependency` wiring and
execution-order position assignment.
- **Slide-in comments drawer** — `ProjectShowLive` now supports a per-resource
comments side-panel with live count badges.
- **Running dashboard prioritization** — the Overview tab now surfaces late and
near-done projects first, with tier pills (`:late`, `:near_done`, `:on_track`).
- **Derived status + soft-hide archive** — replaced the string `status` column
with `archived_at` timestamp. `Project.derived_status/2` returns `:running`,
`:completed`, `:overdue`, `:scheduled`, `:setup`, `:archived`, or `:template`.
`Projects.archive_project/1` / `unarchive_project/1` are the public API.
- **Reusable UI components** — extracted `<.derived_status_badge>`,
`<.empty_state>`, `<.page_header>`, `<.running_card>`, `<.sortable_table>`,
`<.stat_tile>`, `<.tabs_strip>`, and `<.tier_pill>` from the large LiveViews
into individual `PhoenixKitProjects.Web.Components.*` modules.
- **`handle_params/3` refactor** — all list, show, and form LiveViews moved their
initial DB queries from `mount/3` to `handle_params/3` so HTTP render and
WebSocket connect share a single query path.
- **Translations JSONB validation** — schema changesets now validate the shape
of incoming `translations` maps to prevent malformed JSONB inserts.
### Changed
- `build_group_tree/4` and `build_closure_tree/3` switched from `cond do` with
a single non-`true` clause to `if/else` (credo compliance).
- `wire_closure_dependencies/3` nesting reduced by extracting
`wire_child_dependency/4` and `wire_assignment_dependency/2`.
- `is_template_attr?/1` renamed to `template_attr?/1` per Elixir naming
conventions.
### Fixed
- **Diamond-dependency skip in closure pull** — a task reachable via both an
excluded and a non-excluded parent is now correctly emitted once when the
non-excluded branch reaches it.
- **O(n²) topo append eliminated** — `topological_insertion_order/2` now builds
the list in reverse and flips once at the end.
- **Duration editor prefill** — the inline duration editor in `ProjectShowLive`
now falls back to the task template's default values when the assignment has
no explicit duration.
- **Inline duration editor UX** — improved hover contrast, control sizing, and
input prefill behavior.
- **Precommit hygiene** — resolved all credo strict issues and suppressed a
Dialyzer false-positive on recursive `MapSet` opacity.
## 0.1.1
Quality sweep + re-validation pass (PR #2) plus post-merge follow-up
fixes (PR #2 review).
### Added
- `Activity.log_failed/2` helper that tags `metadata.db_pending = true`
so audit-feed readers can distinguish attempted-but-failed mutations
from completed ones during a DB outage.
- `@spec` declarations across the public `Projects` context API
(~32 functions) plus shared `@type uuid` and `@type error_atom`.
- `error_summary/2` translates Ecto validator messages via
`Gettext.dgettext`/`dngettext` against the `errors` domain, and
humanizes field names in the cross-field flash summary.
- Test infrastructure: full LiveView smoke-test stack
(`PhoenixKitProjects.LiveCase`, `Test.Endpoint`, `Test.Router`,
`assign_scope` hook, `assert_activity_logged/2`), self-contained
setup migration under `test/support/postgres/migrations/`, and
`test.setup` / `test.reset` mix aliases.
### Changed
- `Activity.log/2` rescue widened to the canonical post-Apr shape
(`Postgrex.Error -> :ok`, `DBConnection.OwnershipError -> :ok`,
`e -> Logger.warning`, `catch :exit, _ -> :ok`).
- `enabled?/0` gained `catch :exit, _ -> false` for sandbox-shutdown
resilience.
- `recompute_project_completion/1` now wraps the read + check + update
in a transaction so two concurrent assignment status changes can't
double-mark a project completed.
- `add_dependency/2` runs the cycle check + insert in a `:serializable`
transaction; concurrent edge inserts that would close a cycle now
fail with a friendly retry-hint changeset error.
- `create_project_from_template/2` opens its outer transaction at
`:serializable` so the cycle-race protection inside `add_dependency/2`
actually applies on the template-cloning path (Postgres ignores
isolation level on nested transactions).
- All 5 admin LiveViews emit `Logger.debug` on `handle_info` catch-alls
(was silent).
- `phx-disable-with` on every destructive `phx-click` site
(`project_show_live` × 9, `assignment_form_live` × 3, `task_form_live` × 2,
delete buttons in `projects_live` / `tasks_live` / `templates_live`).
- `Project.changeset/2` `name_index_for/2` picks the partial-index
constraint name based on `is_template`, so a template and a project
can share a name freely. Coercion accepts the full set of truthy
forms (`true`, `"true"`, `"1"`, `1`, `"on"`).
- Cross-module schema typespecs relaxed to `struct() | nil` until
`phoenix_kit_staff` 0.1.1 ships `@type t` declarations
(tracking: `BeamLabEU/phoenix_kit_staff#3`).
### Fixed
- `add_dependency/2` was TOCTOU under concurrent inserts (PR #1
review #2).
- `assignment_status_counts/0` was filtering on `is_template == false`
but not `status == "active"`, inflating the dashboard's todo /
in_progress / done totals with archived projects' assignments
(PR #1 review #4).
- Template + project name unique-constraint collision via core's
V105 partial-index split (PR #1 review #5).
- `apply_template_dependencies/1` rollback no longer silently
swallowed — surfaces a `:warning` flash + Logger.warning
(PR #1 review #6).
- `do_update_progress/3`, `save_duration`, and `remove_dependency`
in `ProjectShowLive` now route their error branches through
`Activity.log_failed/2`, closing the `db_pending: true` invariant
gap surfaced by the PR #2 review.
- `test_helper.exs` no longer hard-fails when `psql` is missing —
the reachability probe falls through to the connect-attempt path,
matching the AGENTS.md "never hard-fail on a missing DB" contract.
### Coverage / quality
- Test count: 56 → 355 (+299), 0 flakes across 10/10 stable runs.
- Line coverage: 37.02% → 91.80%.
- Dialyzer: 6 pre-existing unknown-type warnings → 0 errors.
- Credo `--strict`: 0 issues.
## 0.1.0
- Initial release: project + task management with polymorphic assignees
(team / department / person), per-project and template-level dependencies
with cycle detection, atomic template cloning, weekday-aware schedule math,
PubSub broadcasts, and activity logging.