Skip to content

SRS - v1.1

Field Value
Version 1.1
Product NepWalk
Company Tech Everest
Author Prakash (Product Team)
Last Updated 2026-03-15
Hard Deadline 2026-04-24 (Internal Buffer: 2026-05-24)
Launch Date 2026-04-29

Table of Contents

  1. Introduction
  2. System Architecture
  3. User Roles
  4. Core Data Structure
  5. Authentication & User Management
  6. Functional Requirements
  7. API Requirements
  8. Database Design
  9. Non-Functional Requirements
  10. Out of Scope (MVP)
  11. Milestones & Demo Plan
  12. Tools & Communication

1. Introduction

1.1 Purpose

This document defines the Software Requirements Specification (SRS) for the NepWalk MVP. It translates the Business Requirement Specification (BRS) into technical system requirements to guide software development.

Intended audience:

  • Backend developers
  • Frontend developers
  • QA engineer
  • Product manager
  • Project manager

1.2 Product Overview

NepWalk is a Trip Operations System designed to help tour operators manage and share travel itineraries through a structured timeline.

Core problem solved: Nepal travel is dominated by unreliable middlemen, non-transparent pricing, and no single trustworthy platform. NepWalk replaces scattered communication — WhatsApp messages, Facebook posts, emails, spreadsheets, multiple itinerary versions — with a single source of truth for trip timelines.

The MVP focuses primarily on timeline-based itinerary management.


2. System Architecture

2.1 Technology Stack

Layer Technology
Frontend Next.js + TypeScript + PWA
Backend NestJS + Fastify Adapter
API Style REST
Database PostgreSQL
ORM Prisma
Auth OAuth 2.0 (Google) + JWT + Email/Password
Notifications Web Push API (VAPID keys, no third-party)
Deployment Docker + Cloud hosting (post-backend completion)
Docs MkDocs (architecture + tech + product/requirement)
Product Docs Google Docs / Obsidian (business + product)

2.2 Architecture Diagram

Next.js (Frontend + PWA)
        │
        │ REST API
        ▼
NestJS Backend (Fastify Adapter)
        │
        │ Prisma ORM
        ▼
PostgreSQL Database

3. User Roles

3.1 System Admin

Permission Details
Manage user access Full
View all trips Full
Modify any trip Full
Monitor system usage Full

3.2 Tour Leader

Permission Details
Create trips Full
Edit trip timeline Full
Add / edit / delete itineraries Full
Invite trip members (by email) Full
Remove trip members Full
Toggle trip visibility (private/public) Full
Save trip as template Full
Clone template into new trip Full

3.3 Trip Member

Permission Details
View invited trips (dashboard) Full
View itinerary Full
Receive push notifications Full
Modify timeline ❌ Not allowed

3.4 Public Visitor (Not logged in)

Permission Details
View public trip via shareable link Full
Edit anything ❌ Not allowed
Access private trip data ❌ Not allowed

4. Core Data Structure

The system revolves around Trips and Timeline Itineraries.

Trip
 └── Day
      └── Itinerary Items (Activities)

Example Timeline

3 Days in Kathmandu

Day 1

08:00 – 08:45 (45m)   Breakfast at Hotel Yak & Yeti
08:45 – 09:15 (30m)   Drive to Pashupati
09:15 – 11:30 (2h 15m) Visit Pashupati
11:30 – 12:30 (1h)    Lunch at Roadhouse Café
12:30 – 14:00 (1h 30m) Free time / Rest

Decision: Open-ended ("onward") times are removed from MVP. All activities must have a defined start and end time. Time range per day is 05:00 – 23:00. No activity can cross into the next calendar day.


5. Authentication & User Management

5.1 Registration

Two registration methods are supported:

Method 1 — Email / Password

  • User provides name, email, password
  • Password is validated (minimum 8 characters)
  • Password is hashed (bcrypt) before storage
  • Email must be unique in the system

Method 2 — Google OAuth 2.0

  • User clicks "Continue with Google"
  • Google returns profile (name, email, avatar)
  • System creates or links account automatically
  • No password stored for OAuth users

Recommendation for Team: Let's use Google OAuth as the primary method. It is free, removes password management burden, reduces friction, and eliminates email verification complexity. Email/password is kept as a fallback.

5.2 Login

  • Email/password login returns a JWT token
  • Google OAuth login returns a JWT token
  • JWT is stored in the frontend (httpOnly cookie recommended)
  • Token expiry: 7 days

5.3 Forgot Password (Email/Password users only)

  • User enters their registered email
  • System sends a reset link (valid for 1 hour)
  • User sets a new password via the link
  • OAuth-only users see a message: "You signed in with Google. No password to reset."

5.4 Session Handling

  • Protected pages redirect unauthenticated users to login
  • Frontend stores JWT and attaches it to all API requests
  • Logout clears the token from storage

5.5 Role Assignment

Role Assigned by
System Admin Manual / seeded in DB
Tour Leader Default role on registration
Trip Member Assigned when invited to a trip

Every registered user is a Tour Leader by default. A user becomes a Trip Member when invited to a specific trip. These are not mutually exclusive — a user can be a Tour Leader for their own trips and a Trip Member on someone else's.


6. Functional Requirements

6.1 Trip Management

6.1.1 Create Trip

  • Tour Leader fills in: trip title, description (optional), start date
  • Slug is auto-generated at creation time: {title-slug}-{YYYY}-{4-char-random}
  • Example: everest-camp-2026-x4k2
  • Slug is unique across the system
  • Slug is not editable in MVP
  • Default visibility: Private
  • Trip is saved to DB and Tour Leader is set as owner

6.1.2 Edit Trip

  • Tour Leader can edit: title, description, start date, visibility toggle
  • Endpoint: PUT /trips/:id

6.1.3 Delete Trip

  • Tour Leader or Admin can delete a trip
  • Requires confirmation dialog before deletion
  • Cascades: deletes all days, itineraries, version logs for that trip

6.1.4 View Trip List

  • Tour Leader sees all trips they created
  • Trip Member sees all trips they have been invited to
  • Both shown on their respective dashboards

6.1.5 Visibility Toggle

  • Tour Leader can toggle trip between Private and Public
  • Private: Only invited members can view the trip
  • Public: Anyone with the shareable URL can view the trip
  • Default on creation: Private

6.2 Trip Member Management

6.2.1 Invite Member

  • Tour Leader enters the invitee's email address
  • System checks if email is a registered user:
  • If registered: Trip member record is created immediately. Member sees the trip in their dashboard.
  • If not registered: Invitation is stored as pending. When the user registers with that email, they are automatically linked to the trip.
  • Invitation email is sent in both cases (registered and pending)

6.2.2 Remove Member

  • Tour Leader can remove any member from a trip
  • Member loses access immediately
  • Member's push notification subscription for that trip is cancelled

6.2.3 View Members

  • Tour Leader can view the full member list for a trip
  • Shows: name, email, role, invite status (active / pending)

6.2.4 Access Control Rules

User Private Trip Public Trip
Tour Leader (owner) Full access + edit Full access + edit
Invited Trip Member View only View only
Public Visitor ❌ No access View only
Other Tour Leaders ❌ No access View only

6.3 Day Management

6.3.1 Day Model

Each trip contains one or more days. Days are ordered by day_number (ascending). No custom manual reorder in MVP — Day 1 is always first.

6.3.2 Add Day

  • Tour Leader adds a day to a trip
  • Day number is auto-incremented
  • Optional: day title (e.g., "Arrival Day", "Acclimatisation")

6.3.3 Edit Day

  • Tour Leader can edit day title

6.3.4 Delete Day

  • Deleting a day deletes all its itinerary items
  • Confirmation required before deletion

6.4 Timeline Builder (Itinerary Management)

This is the core feature of the NepWalk MVP.

6.4.1 Activity Fields

Each itinerary item must include:

Field Required Notes
start_time ✅ Yes Min 05:00, max 22:59
end_time ✅ Yes Must be after start_time. Max 23:00.
title ✅ Yes Short label
description ❌ Optional Longer detail
location ❌ Optional Name of place
map_link ❌ Optional Google Maps / Apple Maps URL or coordinates
notes ❌ Optional Internal notes for the group
order_index ✅ System For reordering within a day

Example:

start_time: 08:00
end_time:   08:45
title:      Breakfast
location:   Hotel Yak & Yeti
notes:      Buffet included. Meet in lobby at 07:55.
map_link:   https://maps.google.com/?q=HotelYakYeti

6.4.2 Time Rules

  • Time range per day: 05:00 to 23:00 (no activity may end after 23:00)
  • end_time must be after start_time
  • No overlapping activities within the same day
  • Backend validates and rejects overlapping time ranges
  • Frontend shows a clear validation error
  • Duration is auto-calculated: end_time - start_time
  • Duration is displayed in the UI (e.g., 45m, 2h 15m)
  • Activities crossing midnight are not supported in MVP

6.4.3 Add Activity

  • Tour Leader opens an add form / modal
  • All required fields filled, optional fields skipped if not needed
  • System validates time range and overlap before saving
  • Activity is appended to the day (highest order_index + 1)

6.4.4 Edit Activity

  • Tour Leader can edit all fields
  • On save, overlap validation runs again
  • If time is changed, a version log entry is created

6.4.5 Delete Activity

  • Confirmation required
  • A version log entry is created on deletion

6.4.6 Reorder Activities

Decision: Use explicit Up/Down buttons in MVP. No drag-and-drop.

Rationale: drag-and-drop adds frontend complexity, mobile UX issues, and requires careful state management. Up/Down arrows are reliable, fast to build, and sufficient.

  • Tour Leader can move any activity up or down within its day
  • Backend endpoint: PATCH /itineraries/reorder — accepts an ordered array of itinerary IDs for a given day
  • On reorder, a version log entry is created

6.4.7 Timeline Display Format

08:00 – 08:45 (45m)
Breakfast at Hotel Yak & Yeti
  • Activities sorted by start_time ascending
  • Duration calculated and shown in parentheses
  • Map link shown as a button/icon if present

6.5 Trip Sharing Page

6.5.1 Public URL

Each trip has a unique public URL:

nepwalk.com/trip/everest-camp-2026-x4k2
  • Slug is generated at trip creation (see 6.1.1)
  • Public URL is always accessible but only shows content if trip is Public
  • If trip is Private, the public URL returns a "Trip not available" message

6.5.2 Public Page Content

The public sharing page shows:

  • Trip title
  • Trip description
  • All days with their titles
  • All itinerary items per day (start time, end time, duration, title, location, notes)
  • Map link button (if present, opens in default map app)
  • Latest version info (version number, last edited by, timestamp)

6.5.3 Read-Only Enforcement

  • No edit controls are shown to public visitors
  • Public API endpoint exposes only allowed fields — no member list, no private management data

6.5.4 Mobile-Friendly Layout

  • Timeline is readable on small screens
  • Map link buttons are touch-friendly
  • Responsive design required

6.6 Version Log

6.6.1 What Triggers a New Version

A version log entry is created when:

Event Triggers version?
Activity added ✅ Yes
Activity deleted ✅ Yes
Activity time changed (start or end) ✅ Yes
Activities reordered ✅ Yes
Activity title / description / notes / location edited ❌ No
Day added or deleted ❌ No (MVP)

Field edits (title, notes, description) do NOT create a version in MVP. Version log tracks schedule changes only.

6.6.2 Version Entry Structure

Each version log entry stores:

Field Example
version_number 3
trip_id (FK to trips)
edited_by John (user display name)
timestamp 2026-04-01 10:30
change_description Optional short note from Tour Leader

Example:

Version 3
Edited by: John
Time: 2026-04-01 10:30

Change: Lunch moved from 12:00 → 13:00

6.6.3 Version Display

  • Version list accessible to Tour Leader and Trip Members
  • Latest version shown at the top
  • Public sharing page shows latest version info (version number + timestamp only)
  • Tour Leader can optionally add a short change note when saving a version-triggering change

6.6.4 Version Granularity

  • Trip-level versioning: One version entry per save action, not per individual field
  • Single reorder action = one version entry (not N entries for N items moved)

6.7 Template System

6.7.1 Save as Template

  • Tour Leader can save any of their trips as a template
  • Template stores: template name, all days, all itinerary items (title, times, description, location, notes, map_link)
  • Templates are per-user — not visible to other users on the platform

6.7.2 Clone Template

  • Tour Leader selects a saved template
  • System creates a new trip with all days and itinerary items copied
  • Members are NOT copied — the new trip starts with no members
  • Dates are NOT auto-set — Tour Leader sets dates on the new trip manually
  • Changes to the cloned trip do not affect the original template

6.7.3 Template Management

  • Tour Leader can view their template list
  • Tour Leader can delete a template (does not affect trips already created from it)

6.8 Push Notifications

6.8.1 Technology

  • Native Web Push API with VAPID keys
  • No third-party service dependency (no Firebase FCM)
  • Service worker handles push events on the frontend
  • VAPID keys generated once and stored in backend environment variables

6.8.2 Subscription Flow

  • On first visit to a trip page (as a Trip Member), browser prompts for notification permission
  • If granted, browser push subscription is saved to DB (linked to user + trip)
  • If denied, notifications are silently skipped for that user

6.8.3 Who Receives Notifications

  • All Trip Members of a trip are auto-subscribed on joining
  • No notification preference UI in MVP — opt-out is only via browser-level permission denial

6.8.4 Trigger Events

Notifications are sent when:

  • Activity is added
  • Activity is deleted
  • Activity time is changed

6.8.5 Notification Format

Trip Update — Everest Camp 2026

Lunch time changed
Old: 12:00 – 13:00
New: 13:00 – 14:00

6.8.6 Technical Note for Backend

Spike push notification setup in Milestone 2, not Milestone 5. VAPID key generation, subscription endpoint, and service worker registration should be prototyped early to avoid last-minute integration risk.


  • Each activity can optionally include a map_link
  • Supported formats: Google Maps URL, Apple Maps URL, coordinates
  • Map button is only shown in UI if map_link is present
  • On click, opens in the device's default map application
  • Basic URL format validation before save (must start with http)

6.10 PWA Support

Feature MVP?
Web app manifest (name, icon, theme color, start URL) ✅ Yes
Service worker (cache static assets) ✅ Yes
Installable on device ✅ Yes
Offline viewing of previously loaded itinerary ✅ Yes
Offline editing ❌ No

7. API Requirements

All endpoints are REST. JWT token required on all protected endpoints (via Authorization: Bearer header).

Authentication

POST   /auth/register
POST   /auth/login
POST   /auth/forgot-password
POST   /auth/reset-password
GET    /auth/google               OAuth redirect
GET    /auth/google/callback      OAuth callback
POST   /auth/logout

Trips

POST   /trips                     Create trip (Tour Leader)
GET    /trips                     List trips for logged-in user
GET    /trips/:id                 Trip detail (private, auth required)
PUT    /trips/:id                 Edit trip
DELETE /trips/:id                 Delete trip
GET    /trips/public/:slug        Public trip page (no auth required)

Trip Members

POST   /trips/:tripId/members          Invite member by email
GET    /trips/:tripId/members          List members
DELETE /trips/:tripId/members/:userId  Remove member

Days

POST   /trips/:tripId/days        Add day
GET    /trips/:tripId/days        List days for a trip
PUT    /trips/:tripId/days/:id    Edit day title
DELETE /trips/:tripId/days/:id    Delete day

Itineraries

POST   /itineraries               Add activity to a day
PUT    /itineraries/:id           Edit activity
DELETE /itineraries/:id           Delete activity
PATCH  /itineraries/reorder       Reorder activities (ordered array of IDs)

Version Log

GET    /trips/:id/versions        Fetch all versions for a trip

Templates

POST   /templates                 Save trip as template
GET    /templates                 List user's templates
DELETE /templates/:id             Delete template
POST   /templates/:id/clone       Clone template into new trip

Push Notifications

POST   /notifications/subscribe   Save browser push subscription
DELETE /notifications/subscribe   Remove subscription

8. Database Design

Core Tables

users
  id, name, email, password_hash (nullable for OAuth),
  avatar_url, auth_provider (email | google),
  role (admin | leader),
  created_at, updated_at

trips
  id, title, slug (unique), description, start_date,
  visibility (private | public),
  created_by (FK: users),
  created_at, updated_at

trip_members
  id, trip_id (FK: trips), user_id (FK: users),
  role (leader | member),
  status (active | pending),
  invited_email (for pending invites),
  created_at

days
  id, trip_id (FK: trips), day_number, title,
  created_at, updated_at

itineraries
  id, day_id (FK: days),
  start_time, end_time,
  title, description, location, map_link, notes,
  order_index,
  created_at, updated_at

activity_versions
  id, trip_id (FK: trips),
  version_number, edited_by (FK: users),
  change_type (added | deleted | time_changed | reordered),
  change_description (nullable),
  snapshot (JSONB — optional, stores trip state at that version),
  created_at

templates
  id, name, created_by (FK: users),
  created_at, updated_at

template_days
  id, template_id (FK: templates), day_number, title

template_itineraries
  id, template_day_id (FK: template_days),
  start_time, end_time, title, description,
  location, map_link, notes, order_index

push_subscriptions
  id, user_id (FK: users), trip_id (FK: trips),
  endpoint, p256dh, auth_key,
  created_at

9. Non-Functional Requirements

Performance

  • Timeline load time: < 2 seconds
  • Support at least 100 concurrent users per trip

Security

  • Role-based access control on all protected endpoints
  • JWT authentication
  • Private trips return 403 for unauthenticated and uninvited users
  • Public API endpoint must not expose private data (member list, internal notes — decision: notes are visible on public page as they are part of the itinerary)
  • All inputs validated and sanitised (Prisma + NestJS class-validator)
  • HTTPS enforced in production

Note on notes visibility: Activity notes are shown on the public sharing page. Tour Leaders should be informed of this. If a note is truly internal, the description field should not be used for sensitive information.

Compatibility

Platform Support
Desktop browsers ✅ Chrome, Safari, Edge, Firefox
Mobile browsers ✅ Android Chrome, iOS Safari
PWA installed

Offline Support

  • Previously loaded itinerary pages are viewable offline (service worker cache)
  • Offline editing is not required

10. Out of Scope (MVP)

The following will not be built in this MVP:

  • AI itinerary editing
  • Guide / driver login
  • Vehicle tracking
  • Vendor portals
  • Hotel dashboards
  • Restaurant ordering
  • Payment system
  • Booking engine
  • Marketplace
  • Shared template library (templates are per-user only)
  • Email notifications (push only)
  • Notification preference UI
  • Custom slug editing
  • Offline editing
  • Multi-day activity spanning midnight

11. Milestones & Demo Plan

Note: Each milestone demo is backend only. Frontend completion deadline: April 27.

Milestone 1 — Core System

Deadline: March 20 Demo: Backend API only

Scope:

  • Project setup (NestJS + Prisma + PostgreSQL)
  • User registration (email/password + Google OAuth)
  • JWT auth + session handling
  • Forgot password flow
  • User roles (Admin, Tour Leader)
  • Trip creation (with slug generation)
  • Database schema — core tables

Demo scenarios:

  • Register via email and Google OAuth
  • Login and receive JWT
  • Create a trip, verify slug generated
  • Confirm DB tables and schema

QA tasks: Pull backend repo. Test auth APIs with Postman. Log bugs in ClickUp.


Milestone 2 — Timeline Builder

Deadline: April 3 Demo: Backend API only

Scope:

  • Day CRUD (create, edit, delete)
  • Itinerary CRUD (add, edit, delete, reorder)
  • Time validation (05:00–23:00, no overlaps, end > start)
  • Duration calculation
  • Version log on: add, delete, time change, reorder
  • Push notification spike (VAPID keys, subscription endpoint, service worker prototype)

Demo scenarios:

  • Create a day, add multiple activities
  • Attempt overlapping times (expect 400 error)
  • Reorder activities, verify order persists
  • Verify version log entry created on time change
  • Show VAPID key setup working

QA tasks: Pull backend repo. Test timeline APIs. Test overlap validation edge cases. Log bugs in ClickUp.


Milestone 3 — Trip Sharing Page

Deadline: April 10 Demo: Backend API only (frontend team demos public page UI)

Scope:

  • Public trip API (GET /trips/public/:slug)
  • Visibility toggle (private / public)
  • Public page exposes: title, description, days, itineraries, version info
  • Public page hides: member list, pending invitations
  • Trip member invite API (email-based, pending state support)
  • Member access control enforcement

Demo scenarios:

  • Create trip, toggle public, access via slug
  • Try to access private trip without auth (expect blocked)
  • Invite a registered user and a non-registered email
  • Confirm pending invite resolves on registration

QA tasks: Test public vs private access. Test invite flow. Cross-browser check on public page.


Milestone 4 — Version Log

Deadline: April 17 Demo: Backend API only

Scope:

  • Full version log API (GET /trips/:id/versions)
  • Version entries for all trigger events
  • Optional change description input
  • Version number auto-increment per trip
  • Latest version shown first

Demo scenarios:

  • Perform 5 timeline changes
  • Fetch version log, verify entries and timestamps
  • Add optional change description, confirm it's saved

QA tasks: Test all version trigger events. Test version ordering. Test optional description field.


Milestone 5 — Templates & Notifications

Deadline: April 24 Demo: Backend + Frontend integrated

Scope:

  • Template save from trip
  • Template list and delete
  • Clone template into new trip (no members copied)
  • Push notifications: send on add/delete/time change
  • Full notification flow: subscribe → trigger event → receive notification

Demo scenarios:

  • Save a trip as template
  • Clone template, verify days and activities copied, members not copied
  • Trigger an itinerary change, receive push notification on another device

QA tasks: Full regression test. Notification testing (permission prompt, receive message, open app from notification). Mobile PWA test.


Final Launch Preparation

Date: April 24–27

  • QA regression testing
  • Bug fixes
  • UI polish
  • Deployment setup (Docker, cloud, env vars, migrations)
  • HTTPS confirmation
  • Smoke test: login → create trip → add timeline → share → edit → see version → receive notification

MVP Launch

Date: April 29

Expected state:

  • NepWalk MVP operational
  • Tour Leaders creating and managing trips
  • Timelines actively used
  • Itineraries publicly shareable
  • Push notifications functioning
  • Manna group (first client) on-boarded as beta users

12. Tools & Communication

Tool Purpose
Slack Official team communication
WhatsApp Quick informal chat
ClickUp Tickets, task tracking, QA bug reports
MkDocs Architecture and technical documentation
Google Docs Business and product documentation
GitHub Code repository (assumed)

QA Process

  • QA pulls frontend and backend repos after each milestone is declared complete
  • QA runs the project locally
  • QA tests against milestone scope and acceptance criteria
  • QA creates bug tickets in ClickUp with steps to reproduce
  • QA is involved from Milestone 1 onwards — not after launch

Appendix A — Slug Generation Rule

Slug format: {title-slug}-{YYYY}-{4-char-random}

Rules:

  • Title converted to lowercase, spaces replaced with hyphens, special characters removed
  • Year is the trip start year (or creation year if start date not set)
  • 4-character random alphanumeric suffix for uniqueness
  • Collision check on insert; regenerate suffix if collision (extremely rare)
  • Slug is immutable after creation

Examples:

Trip Title Generated Slug
Everest Camp 2026 everest-camp-2026-x4k2
Kathmandu Cultural Tour kathmandu-cultural-tour-2026-m9r1
Nepal Mission Trip nepal-mission-trip-2026-3kp7

Appendix B — Open Architecture Decisions (Resolved)

Decision Resolution
Invite mechanism Email-based. Registered users linked immediately. Unregistered stored as pending.
Auth method Google OAuth (primary) + Email/Password (fallback)
Password reset Yes, included in MVP
Open-ended times Removed. All activities require start and end time.
Time range 05:00 – 23:00. No cross-midnight activities.
Overlap validation Not allowed. Backend rejects overlapping times with 400 error.
Reorder UX Up/Down buttons. No drag-and-drop in MVP.
Day ordering By day_number ascending. No manual reorder.
Slug generation Auto at creation, immutable, format: title-year-random4
Trip visibility default Private
Version triggers Add, delete, time change, reorder only. Field edits do not trigger.
Version granularity Trip-level. One entry per save action.
Templates scope Per-user only. No shared library.
Template clone Copies days + activities only. Members and dates not copied.
Notification provider Native Web Push API with VAPID keys. No FCM.
Notification subscription Auto-subscribed on joining a trip. No preference UI.
Notes on public page Visible. Tour Leaders informed to keep notes appropriate.

End of Document — NepWalk MVP SRS v1.1