TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
A focused workspace for small teams. Organize projects, track tasks, and keep work moving with Hostlink.
ProductivityTypeScript · HTMLGitHub @abhayjais17OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Where teams host their work — A focused project tracker for small teams, built for hackathon PS 09.
Hostlink sits between scattered chat threads and heavyweight tools like Jira, giving teams enough structure to stay aligned without the complexity of enterprise project management software.Read the full README ↗Where teams host their work — A focused project tracker for small teams, built for hackathon PS 09.
Hostlink sits between scattered chat threads and heavyweight tools like Jira, giving teams enough structure to stay aligned without the complexity of enterprise project management software.
Small teams need clarity on who's doing what, when things are due, and what's ready to ship — but most tools either bury you in features you'll never use or leave you stitching updates together from Slack threads. Hostlink gives teams a shared workspace that's light enough to use daily and clear enough to trust.
Implemented:
hostlink/
├── app/ # Next.js App Router pages and API routes
│ ├── (app)/ # Main app layout group
│ │ ├── [section]/ # Dynamic routes for /my-tasks, /analytics, /team, /settings
│ │ └── projects/ # Project routes
│ │ ├── [id]/ # Project detail with [[...view]] catch-all for /board, /list, /analytics
│ │ └── page.tsx # Projects home
│ ├── api/ # API Route Handlers
│ │ ├── users/ # GET /api/users
│ │ ├── projects/ # CRUD for projects
│ │ │ └── [id]/ # Project detail, tasks, analytics
│ │ ├── tasks/ # Task CRUD, move, comments
│ │ ├── comments/ # Comment deletion
│ │ └── my-tasks/ # Personal task list
│ ├── login/ # Demo login page
│ ├── page.tsx # Marketing landing page
│ └── layout.tsx # Root layout
├── components/ # React components
│ ├── analytics/ # Chart components (burndown, completion ring, workload)
│ ├── board/ # Kanban board, columns, task cards, quick-add
│ ├── landing/ # Marketing page, login page, product preview
│ ├── layout/ # App shell, sidebar, topbar, breadcrumbs, search
│ ├── list/ # Task table, status dropdown, filters
│ ├── projects/ # Project list, cards, new project modal
│ ├── task/ # Task drawer, modal, fields, activity feed, toolbar
│ ├── ui/ # Base UI components (button, dialog, badge, etc.)
│ └── workspace/ # My Tasks, Team, Settings, Workspace Analytics
├── lib/ # Utilities and business logic
│ ├── api.ts # API client functions (calls backend routes)
│ ├── db.ts # Prisma client singleton
│ ├── hooks.ts # React hooks (useSWR wrappers)
│ ├── seed.ts # Database seed script
│ ├── store.ts # Zustand state (UI state only, domain data from API)
│ ├── types.ts # TypeScript types
│ ├── utils.ts # Utility functions (transitions, analytics, sorting)
│ └── *.test.ts # Test files
├── prisma/
│ └── schema.prisma # Database schema
├── public/ # Static assets
├── .env # Environment variables
├── package.json # Dependencies and scripts
└── README.md # This file
The database uses Prisma ORM with the following tables:
id (String, primary key)name (String)email (String, unique)role (String) — e.g. "Team Lead", "Developer", "Designer"color (String) — for avatar themingcreatedAt (DateTime)id (String, primary key)name (String)description (String, optional)color (String) — for project card/iconcreatedAt (DateTime)updatedAt (DateTime, optional)members (ProjectMember[]), tasks (Task[]), taskEvents (TaskEvent[])id (String, primary key, auto-generated UUID)projectId (String, foreign key)userId (String, foreign key)(projectId, userId)id (String, primary key)key (String, unique) — e.g. "HL-12"projectId (String, foreign key)title (String)description (String, optional)assigneeId (String, foreign key → User)priority (String) — "urgent" | "high" | "normal"status (String) — "backlog" | "in_progress" | "review" | "done"dueDate (String) — ISO date format (yyyy-MM-dd)createdAt (DateTime)movedAt (DateTime) — last status changecompletedAt (DateTime, optional) — set when status becomes "done"comments (Comment[]), events (TaskEvent[])(projectId, status), assigneeIdid (String, primary key)taskId (String, foreign key)authorId (String, foreign key → User)body (String)createdAt (DateTime)taskIdid (String, primary key)taskId (String, foreign key)projectId (String, foreign key)userId (String, foreign key → User)fromStatus (String, optional) — null for task creationtoStatus (String)createdAt (DateTime)(projectId, createdAt), taskIdCascading Deletes: Deleting a project cascades to its tasks, comments, project members, and task events. Deleting a task cascades to its comments and events.
All routes return JSON. Errors return { error: string } with appropriate HTTP status codes.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/users | List all users |
| GET | /api/projects | List projects with computed stats (task count, completion %, overdue count) |
| POST | /api/projects | Create a new project |
| GET | /api/projects/:id | Get project details |
| PATCH | /api/projects/:id | Update project (name, description, color, members) |
| DELETE | /api/projects/:id | Delete project (cascades) |
| GET | /api/projects/:id/tasks | List tasks for a project (supports ?q=, ?assignee=, ?priority=, ?status= filters) |
| POST | /api/projects/:id/tasks | Create a task in a project |
| GET | /api/projects/:id/analytics | Per-project analytics (completion %, burndown, workload, overdue) |
| GET | /api/tasks/:id | Get task details with comments and events |
| PATCH | /api/tasks/:id | Update task fields (title, description, assignee, priority, due date) |
| DELETE | /api/tasks/:id | Delete task (cascades) |
| POST | /api/tasks/:id/move | Move task to new status — validates transition, updates status, stamps timestamps, creates TaskEvent. Returns 422 with { error, allowed: [...] } on invalid transitions. |
| GET | /api/tasks/:id/comments | List comments for a task |
| POST | /api/tasks/:id/comments | Add a comment to a task |
| DELETE | /api/comments/:id | Delete a comment |
| GET | /api/my-tasks?userId= | Tasks assigned to a user across all projects |
Enforced server-side in /api/tasks/:id/move:
| From Status | Allowed To |
|---|---|
| Backlog | In Progress |
| In Progress | Backlog, Review |
| Review | In Progress, Done |
| Done | Review (reopen) |
Invalid transitions return HTTP 422 with { error: string, allowed: Status[] }.
# Clone the repository
git clone <your-repo-url>
cd hostlink
# Install dependencies
npm install
# or
pnpm install
# Set up environment variables
# Create a .env file in the project root (see Environment Variables section below)
# Initialize the database
npx prisma db push
# Seed the database with demo data
npx tsx lib/seed.ts
# Run the development server
npm run dev
The app will be available at http://localhost:3000.
Create a .env file in the project root with the following variables:
| Variable | Purpose | Example Value |
|---|---|---|
DATABASE_URL | Prisma database connection string | file:./dev.db (SQLite) or postgresql://... (Postgres) |
For SQLite (default, local development):
DATABASE_URL="file:./dev.db"
For Postgres (production):
DATABASE_URL="postgresql://user:password@host:5432/hostlink?schema=public"
Note: The schema in prisma/schema.prisma supports both SQLite (provider = "sqlite") and PostgreSQL. For production deployment, change the provider to "postgresql" and update DATABASE_URL.
| Script | Command | Description |
|---|---|---|
dev | npm run dev | Start the Next.js development server (Turbopack) on port 3000 |
build | npm run build | Build the production bundle |
start | npm run start | Start the production server |
test | npm run test | Run the test suite (via tsx --test) |
typecheck | npm run typecheck | Run TypeScript type checking without emitting files |
| Prisma | ||
prisma db push | npx prisma db push | Push the Prisma schema to the database (creates/updates tables) |
prisma generate | npx prisma generate | Generate the Prisma Client |
prisma studio | npx prisma studio | Open Prisma Studio to browse and edit database data |
| Seed | ||
seed | npx tsx lib/seed.ts | Populate the database with demo users, projects, and tasks |
The project includes test files (lib/*.test.ts) that were written for an earlier in-memory implementation. These tests are currently not functional and need to be rewritten to work with the real Prisma database and API routes.
Test coverage areas (to be updated):
To run tests (once updated):
npm run test
Recommended approach for test updates:
test.db via DATABASE_URL)prisma db push before tests to initialize the schemabeforeEach hooksjest-mock-extended or vitestHostlink is optimized for deployment on Vercel (Next.js's native platform):
Push your code to GitHub/GitLab/Bitbucket
Import the project on Vercel
Set environment variables in the Vercel dashboard:
DATABASE_URL="file:./dev.db"DATABASE_URL to the connection stringUpdate prisma/schema.prisma for Postgres:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
Add a build command (if not auto-detected):
prisma generate && next buildnpm install (or pnpm install if using pnpm)Deploy
After deploying, seed the database:
Option 1: Via Vercel CLI
vercel env pull .env.local
npx tsx lib/seed.ts
Option 2: Create a one-time seed API route
// app/api/seed/route.ts
import { exec } from 'child_process'
import { promisify } from 'util'
const execAsync = promisify(exec)
export async function POST(request: Request) {
// Add authentication/secret check here
const { secret } = await request.json()
if (secret !== process.env.SEED_SECRET) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
await execAsync('npx tsx lib/seed.ts')
return Response.json({ success: true })
}
Then call POST /api/seed once with your secret, then delete the route.
Hostlink includes a "Continue as demo user" flow — no authentication required, perfect for hackathon demonstrations or trying the app.
The seeded database includes three users you can switch between:
u1u2u3All demo users are members of both projects and own various tasks.
/projects)Built for Hackathon PS 09 | © 2026 Hostlink | Demo preview — No persistent storage beyond the database