charleslightjarvis/laravel-todo
A Laravel package for adding todo lists and task management to your application. It offers a simple way to create, track, and organize to-dos, with models, migrations, and a clean API that fits naturally into Laravel projects.
Architecture fit
todos table (todos + creator morphs) is a good fit for a platform where "work items" attach to heterogeneous domain entities (User, Project, Team). Avoids N per-model join tables.$model->todos() for relationship-oriented code, Todo::for($model) for query-oriented code. Both are conventional Laravel ergonomics and reduce onboarding cost.TodoCreated, TodoCompleted, TodoCancelled are explicitly "coming soon"). Without them, any decoupled integration (notifications, webhooks, analytics, search indexing, audit log) must poll or be hard-wired into application code — which inverts the dependency direction and is the single biggest architectural constraint on this release.creator tracking is present but there is no assignee/owner relation. Todos belong to the model they're attached to and record who created them; there is no first-class "assigned to a different user" concept. Confirm whether that gap is acceptable or whether creator will be overloaded.Integration feasibility
Todo facade alias is a collision risk in a codebase that already has a Todo model, facade, or service — very likely in a task-adjacent domain. Verify alias registration and plan to alias/rename on import.Technical risk
todos:prune yet and no stated retention policy: the table grows unbounded, and deleted parent models may leave orphaned polymorphic rows unless foreign-key/morph cleanup exists. Confirm whether nullableMorphs + cascadeOnDelete is actually enforceable for polymorphic columns (it generally isn't).Key questions
overdue() and dueToday(), and what is the timezone behaviour?creator intended to serve both roles?morphMap respected for creator and todos relations (string vs. class storage)?Stack fit
Migration path
HasTodos to the first model, ship.tasks/todos table): treat as a data migration project.
pending | in_progress | completed | cancelled and priority onto low | medium | high; document lossy mappings (e.g. blocked → ?).todos rows from the legacy table, resolving todos_type/todos_id and creator_type/creator_id.assignee_id, decide now whether to persist that in a side table or drop the concept — the package will not store it.Compatibility
^1.0 and commit the lockfile; do not float.Todo symbols (class, facade, alias, Livewire component, JS namespace) and resolve collisions up front.morphMap behaviour if the app uses morph maps — mismatched storage between class names and aliases is a common and painful source of silent empty results.users/models table assumptions hold.Sequencing
HasTodos to one low-risk model, exercise every scope, verify config publishing and facade alias behaviour.TodoService) so the package is swappable and events can be synthesized manually until upstream events land.Project todos), one team, one release cycle.Maintenance
Support
Scaling
(todos_type, todos_id, status) and (todos_type, todos_id, due_at) to keep pending()/overdue() selective as the table grows.overdue() and dueToday() are date-range scans — fine with an index, but dueToday() is timezone-sensitive and should be evaluated per-request in the user's timezone, not the app default.creator (with('creator')) in list views; the polymorphic creator relation is an easy N+1.Failure modes
deleting observers or a periodic reconciliation job.TodoCompleted, notifications, webhooks, and analytics silently don't fire. Until events ship, dispatch application-level events from the service wrapper for every state transition.Todo symbol at autoload/boot time — caught in the spike, not in production.Ramp-up
create, completeTodo, scopes, for()), and the mental model is one polymorphic table. Estimate under half a day to first productive use.How can I help you explore Laravel packages today?