Project management SaaS for freelancers
Knoxt.io
A full-stack freelancer project management SaaS for managing clients, collaborative projects, Kanban tasks, notes, project knowledge, notifications, and deployment-ready workflows.

01 · The problem
Knoxt.io
Context
Freelancers keep client work in a CRM, a task board, a notes app, and chat, all at once.
Decisions and requirements get lost in chat threads, nothing links a client to the tasks and notes about them, and inviting a client into a tool usually means giving them access to everything.
02 · What I built
Knoxt.io
- 01Modelled one workspace where clients, projects, Kanban tasks, notes, and project knowledge link to each other (27 PostgreSQL models).
- 02Designed a GraphQL API (84 operations) on NestJS + Prisma, inside a Turborepo monorepo with shared types and UI packages.
- 03Built project-level roles (Viewer, Editor, Admin, Owner) checked on the backend, with email invitations.
- 04Added Project Memory (decisions, meetings, action items, requirements) so project context lives longer than a chat thread.
- 05Shipped through CI/CD: lint, type-check, tests, Docker build, Trivy scans, and a SHA-verified VPS deploy.
03 · Decisions & trade-offs
Knoxt.io
Order keys for Kanban drag-and-drop
Each task stores a fractional order key, so moving a card updates one row instead of renumbering every task in the column.
The backend decides permissions
The UI hides or disables controls by role, but the server re-checks every mutation. Hiding a button isn't security.
Version numbers on notes
A save with an outdated expectedVersion is rejected instead of silently overwriting a teammate's edit.
Public links stored as hashes
Share links use random tokens that are stored only as hashes, so a database leak doesn't hand out working links.
04 · Inside the product
Knoxt.io
Architecture
Monorepo designed for product growth
The codebase separates product apps from reusable packages so the React SPA, NestJS API, Prisma schema, shared types, and UI utilities can evolve without turning into one large application folder.
- apps/web for the React product surface
- apps/api for the NestJS GraphQL API
- packages/database, types, config, ui, graphql, and utilities
Customers
Client CRM connected to delivery work
Freelancers can keep customer records close to the projects, notes, and delivery context they belong to, instead of treating contacts as a disconnected address book.
- CRUD customer profiles with email, phone, company, and status
- Soft delete, pagination, detail pages, and related project lists
- Customer links across projects and notes for better context
Collaboration
RBAC, invitations, and Kanban in one workflow
Project membership is enforced in the backend and reflected in the UI, while Kanban interactions stay fast through order keys instead of rewriting every task after drag-and-drop.
- Viewer, Editor, Admin, and Owner permissions
- Invitation token flow with SMTP and in-app notifications
- Custom columns, assignment, tags, priorities, and due dates
Notes
A workspace for structured project knowledge
The notes module works like a lightweight project wiki with hierarchy, rich editing, search, recovery, and secure sharing, so delivery decisions do not disappear into chat threads.
- Parent-child note trees with drag-and-drop movement
- TipTap rich-text editing, autosave, tags, pins, and breadcrumbs
- Permission sharing, subtree sharing, and hashed public links
Memory
Project Memory for decisions and follow-up
Knoxt.io separates reusable delivery knowledge from ordinary task tracking by modeling decisions, meetings, action items, requirements, and activity history.
- Decision logs with reason, impact, and lifecycle status
- Meetings with summaries, recording URLs, and participants
- Action items and requirements with filters, search, and task conversion
Quality
Production pipeline with security gates
The deployment path checks code quality, database schema safety, tests, Docker images, secrets, dependencies, and server SHA before production is updated.
- 72 backend test cases verified in the reviewed environment
- Dependency audit, Trivy secret scan, and container scan
- Fast-forward VPS deployment with health checks
05 · Who can do what
Knoxt.io
| Permission | Viewer | Editor | Admin | Owner |
|---|---|---|---|---|
| View project | ||||
| Edit tasks and notes | ||||
| Invite members | ||||
| Manage roles | ||||
| Delete project |
06 · Release pipeline
Knoxt.io
Nothing reaches the server without passing every step.
- 1Install with frozen lockfile
- 2Prisma validate and generate
- 3Lint and type-check
- 4Run automated tests
- 5Build Docker images
- 6Trivy security scan
- 7SHA-verified VPS deploy
07 · Screens
Knoxt.io



08 · Result
Knoxt.io
What changed
- Live at knoxt.io.vn.
- 72 backend test cases passing across 23 test files.
- Every deploy passes quality and security gates before it reaches the server.
What I'd keep doing
- “Drawing monorepo boundaries that still make sense as the product grows.”
- “Building SaaS permissions that the backend enforces, not just the UI.”
- “Using tests and good DX to keep complex flows readable.”
09 · Engineering notes
Knoxt.io
The detailed version, for engineers who want the specifics.
ArchitectureMonorepo and backend domain structure
- Organized the system as a pnpm/Turborepo monorepo with apps for web and API plus reusable packages for database, shared types, configuration, UI, GraphQL, and utilities.
- Split backend domains around authentication, users, customers, projects, tasks, notes, project knowledge, notifications, and AI sessions.
- Used a resolver-service-repository flow for selected domains, injecting repository interfaces through tokens so business logic stays testable and less coupled to Prisma.
SecurityAuthentication, validation, and authorization
- Implemented email/password authentication with bcrypt cost factor 12, JWT authentication, Passport guards, and Google ID token verification on the backend.
- Linked Google accounts to existing users by email and automatically accepted pending project invitations after signup or Google login.
- Added global validation that strips unknown fields, rejects undeclared input, transforms payloads, validates environment variables at startup, and hides internal GraphQL errors in production.
CollaborationProjects, members, invitations, and Kanban
- Built project CRUD with active, on-hold, completed, and archived states, customer linking, date tracking, recent notes, pinned notes, attachments, and soft delete.
- Implemented Viewer, Editor, Admin, and Owner roles with the backend as the source of permission truth and frontend controls hidden or disabled based on role.
- Developed a drag-and-drop Kanban board with custom columns, assignment, due dates, tags, priorities, task modal create/edit flows, and orderKey-based sorting to avoid rewriting every task on reorder.
NotesHierarchical note workspace and secure sharing
- Built independent and project/customer-linked notes with parent-child hierarchy, drag-and-drop movement, TipTap rich-text editing, tables, task lists, Markdown support, and autosave.
- Added optimistic concurrency through version and expectedVersion values to detect conflicting note updates.
- Supported pinning, tags, case-insensitive search, breadcrumbs, fullscreen editing, soft delete, trash restore, attachment metadata, direct sharing by viewer/editor permission, subtree sharing, and secure public links that store only hashed random tokens.
KnowledgeProject Memory for decisions and delivery context
- Modeled structured project knowledge with decision logs, meetings, action items, requirements, activity logs, and role-based access.
- Supported meeting summaries, recording URLs, internal or external participants, action item owners, due dates, status tracking, and conversion from action item to Kanban task.
- Added unified search and filters across decisions, meetings, requirements, status, priority, and date ranges.
QualityTesting, CI/CD, and production readiness
- Added tests for auth service, project authorization, project service, task service and repository, ordering algorithm, notes, note sharing, Project Knowledge, health checks, SMTP invitation template, Kanban board, Project Memory UI, auth context, and landing page.
- Verified 72 backend test cases passing in the reviewed environment, with the logging suite blocked by sandbox network binding rather than business assertions.
- Built a GitHub Actions pipeline for frozen dependency install, Prisma validation and client generation, Docker Compose validation, lint, type-check, test coverage, builds, tracked-file cleanliness, dependency audit, Trivy secret scanning, image scanning, and SHA-verified VPS deployment.
Stack
Next case study
Ballot Survey & voting platform