The tour
What DailyTM actually does
Everything on this page ships in v2.0.0. Work that is deliberately deferred lives in the backlog, in the repository, with the reason it was cut.
Projects and views
Look at the same work three different ways
Filters, sort, search, and the active view are all URL state, so every arrangement is a link somebody else can open.
Board
Columns from your own statuses, drag between them, and a card that moves the instant you drop it. Ranking is fractional-index, so a hundred consecutive drops into the same gap never collide.
List
A sortable, selectable table with density that suits a long backlog. Cursor-paginated, so a project with ten thousand tasks scrolls rather than stalls.
Calendar
A month grid built from due dates. Every date is stored as timestamptz and formatted through one module, so a deadline means the same thing in two timezones.
My Tasks
Everything assigned to you across every project, grouped into overdue, today, upcoming, and no date — keyed on a status's category, so renaming a column does not empty the list.
Project visibility
A project is open to the whole organization or restricted to named members. Restricted projects store membership rows; open ones store none, so the common case costs nothing.
Command menu
Ctrl/Cmd+K to create a task, jump to a project, invite someone, or search — without leaving the page you are on.

Task modelling
A task shaped like your work, not like our schema
The three things a task manager is judged on, and the search that makes them findable.
Configurable statuses
Add, rename, recolour, and reorder columns per project. Deleting a status that still holds tasks is refused with the count. Every rollup keys on a fixed category, never on the name.
Subtasks
One level deep, deliberately — which keeps the completed-total rollup one query instead of a recursive CTE. Moving a parent moves its children in the same transaction.
Labels
Organization-scoped rather than per-project, so a label means the same thing on every board. Rename it once and every card across every project follows.
Full-text search
A generated tsvector column with a GIN index, over task titles, descriptions, and project names. Results are re-read through the same visibility rule the task list uses, so search has no second copy to drift from.

Collaboration
The half that makes it a team tool
Comments people read, mentions that reach the right person, and a record of what changed.
Comments and rich text
A TipTap editor on both task descriptions and comments, so the mention plumbing is built once. Edit and delete are author-or-admin.
@mentions, resolved on the server
The mentioned-user list is derived from the stored document, never from what the client sent. A mention of somebody who cannot see a restricted project produces no notification, no email, and no hint in the picker.
Inbox and notifications
Unread state, mark-one and mark-all, per-user email preferences, and due-date reminders from a scheduled job whose uniqueness is a database index rather than a flag it checks.
Audit timeline
Every mutation that changes shared state writes an activity row in the same transaction. Admins and owners get an organization-wide timeline, filterable by actor, resource, and date.

Files, people, and money
The parts you only notice when they are missing
Each one is optional. Leave its configuration out and the feature is absent, not broken.
Attachments on any S3 bucket
Presign, upload straight from the browser, then verify with HeadObject — so a client that lies about a file's size is corrected by the store's own answer. Rows key on an object key, never a URL.
Organizations and invitations
Email invitations and shareable links that cannot drift apart, expiry, re-invite cancellation, role changes, and last-owner protection built into the auth layer rather than guarded by hand.
Four roles, defined once
Owner, admin, member, and viewer, in a single file read by both the interface and the server. A control the UI offers is always a control the server allows.
Optional billing
Polar checkout, portal, and signature-verified idempotent webhooks. With no access token the plugin is never registered, every organization is unlimited, and the billing interface is absent.
Under it
Written to be inherited
You are buying a codebase somebody else has to keep working in. These are the decisions that determine whether that is pleasant.
Tenancy is structural
The organization comes from the session, never from a URL. findUnique is banned inside the service layer by a lint rule, because a lookup by id alone is how a foreign row gets returned.
Every service proves its own denial
An .authz.test.ts per service, showing NOT_FOUND across the tenant boundary on read and on write. No service merges without one; it is the release gate, not a nice-to-have.
Layers point one way
Pages to components to routers to services to lib. Services never read the request, routers never touch the database, components never import server code — all three enforced by ESLint rather than by review.
See it with data in it
Sign up free, or clone the repository and run the seed script for a populated workspace where nothing is an empty state.


