TaskNook is a backend-focused portfolio MVP for managing shared tasks inside small private groups (families), build with Expo and NestJS.
This project is not intended to be another generic to-do app. Its main goal is to explore the backend and domain logic behind a collaborative task system:
- authentication and authorization
- invite-based group access
- membership rules
- task lifecycle
- permissions
- filtering, sorting and pagination
- A user signs up or logs in.
- The user creates a private family or join an existing one by invite token.
- Family members create tasks inside a shared task pool.
- Tasks can be filtered, sorted, accepted, assigned, completed, cancelled, or deleted depending on user permissions.
- Each user can track both shared family tasks and their own active tasks.
Create a family, invite members with a code, join another family, and switch between active family contexts to separate different groups.
Create a task with priority, time window, and assignment mode. Open tasks can be accepted by family members, completed from the details screen, and tracked in My Tasks when they are assigned to or accepted by you.
Narrow the shared pool by status and priority, then sort tasks by date or deadline to find the next relevant item faster.
Create an account and use the profile screen to check personal progress across completed, active, and pending tasks.
| Layer | Stack |
|---|---|
| Backend | NestJS, Passport JWT, bcrypt, Zod validation |
| Database | PostgreSQL, Prisma ORM |
| Mobile | Expo, React Native, Expo Router |
| State & API data | TanStack Query, Zustand, Axios |
| Monorepo & tooling | pnpm workspaces, Turborepo, TypeScript |
apps/
api/ NestJS API, Prisma schema, migrations, backend modules
mobile/ Expo mobile prototype
packages/
contracts/ Shared Zod schemas, TypeScript types, and domain contracts
stateDiagram-v2
direction LR
[*] --> PENDING: create task
PENDING --> IN_PROGRESS: accept
IN_PROGRESS --> COMPLETED: complete
IN_PROGRESS --> PENDING: withdraw
COMPLETED --> IN_PROGRESS: resume
PENDING --> [*]: delete
IN_PROGRESS --> [*]: delete
COMPLETED --> [*]: delete
The current version focuses on core backend/domain logic, while production-oriented features are planned in future updates.
| Area | Current State |
|---|---|
| Production readiness | Not security-hardened for production deployment yet |
| Tests | Automated API/domain tests still need to be added |
| Dashboard | Basic summary endpoints only, not full analytics |
| Comments | API endpoints are not implemented yet |
| Realtime | WebSocket/pub-sub runtime is not implemented yet |
| Infrastructure | No Redis caching/pub-sub |
| Files | No S3-compatible storage, avatar uploads, or task attachments yet |
| Notifications | No production push notification flow yet |
| API docs | No Swagger/OpenAPI documentation yet |
| Track | Planned Work |
|---|---|
| Backend quality | Add API tests, domain tests, Swagger/OpenAPI docs, and security hardening |
| Product features | Add WebSocket-based task updates, Android push notifications, custom avatars, along with task attachments and comments |
| Maintainability | Refactor larger services as the domain grows |
- Node.js compatible with the installed dependencies.
- pnpm.
- Docker and Docker Compose for the backend.
- Expo account for EAS Android builds.
- Android device or emulator for the mobile app.
###№ Install Workspace Dependencies
pnpm install
pnpm approve-buildsThe backend runs through Docker Compose with PostgreSQL, Prisma migrations, the NestJS API, and Nginx.
Copy backend environment variables:
cp .env.example .env.prodUpdate secrets in .env.prod before running anything outside local development. Keep PORT=4000, because the current Nginx config proxies requests to the API on port 4000.
Start the backend:
docker compose build #build the image
docker compose up -d #start in detached mode
docker compose logs -f server #check logsStop the backend:
docker compose downWhen running locally, the API is exposed through Nginx at http://localhost. On a VPS, use the VPS IP address or domain.
The mobile app uses Expo and EAS. EXPO_PUBLIC_API_URL must point to a backend URL reachable from the Android device, for example:
http://<VPS_IP>for a VPS backend;http://<LAN_IP>for a backend running on your computer and tested from a physical phone;http://10.0.2.2for an Android emulator talking to a backend on the host machine.
Copy mobile environment variables:
cd apps/mobile
cp .env.example .envSet EXPO_PUBLIC_API_URL in apps/mobile/.env.
Install EAS CLI and log in:
pnpm add --global eas-cli
eas loginFor the preview cloud build, configure the API URL in EAS instead of committing it to eas.json:
cd apps/mobile
eas env:create --name EXPO_PUBLIC_API_URL --value http://<BACKEND_URL> --environment preview --visibility plaintextEXPO_PUBLIC_API_URL is bundled into the mobile app, so treat it as public configuration, not as a secret.
If you also build development or production profiles, create the same variable for those EAS environments as well.
Build an Android preview APK on Expo servers:
eas build --platform android --profile previewInstall the generated APK on your phone from the EAS build link.
For iterative development with a development client, build and install the development APK:
eas build --platform android --profile developmentNote: a preview APK profile is a standalone internal build and does not require pnpm expo start after installation. Use the development profile when you want the installed app to connect to the local Expo dev server.
Then start the local Expo dev server:
pnpm expo start


