SmartScapes is an interactive web app that replaces static maps with dynamic, custom guides for large parks and attractions. Users can track and save routes by “checking in” at points of interest, leave reviews and photos, and filter or share personalized recommendations. An admin panel lets moderators create and manage routes, POIs, media and user‑submitted content.
- Pay attention, that we have certain quality criteria, which we should follow during application development.
SmartScapes is an interactive mapping platform for parks and attractions that provides:
- Dynamic, interactive guides
- Route tracking and check-ins
- User reviews and photo sharing
- Points of Interest (POI) management
- Custom route creation and sharing
- Administrative content moderation
- NodeJS (>=22.10.0 <23.0.0);
- npm (10.x.x);
- PostgreSQL (17.5)
erDiagram
users {
int id PK
dateTime created_at
dateTime updated_at
varchar email
varchar first_name
varchar last_name
boolean is_visible_profile
text password_hash
text password_salt
int group_id FK
}
groups {
int id PK
dateTime created_at
dateTime updated_at
varchar name
varchar key
}
groups_to_permissions {
int id PK
dateTime created_at
dateTime updated_at
int group_id FK
int permission_id FK
}
permissions {
int id PK
dateTime created_at
dateTime updated_at
varchar name
varchar key
}
points_of_interest {
int id PK
dateTime created_at
dateTime updated_at
varchar name
varchar description
geometry location
}
user_follows {
int id PK
dateTime created_at
dateTime updated_at
int follower_id FK
int following_id FK
}
reviews {
int id PK
dateTime created_at
dateTime updated_at
int user_id FK
text content
int likes_count
int route_id FK
int poi_id FK
}
route_categories {
int id PK
dateTime created_at
dateTime updated_at
int route_id FK
int category_id FK
}
categories{
int id PK
dateTime created_at
dateTime updated_at
varchar name
varchar key
}
routes {
int id PK
dateTime created_at
dateTime updated_at
varchar name
varchar description
decimal distance
decimal duration
geometry geometry
int created_by_user_id FK
}
planned_paths {
int id PK
dateTime created_at
dateTime updated_at
int user_id FK
decimal distance
decimal duration
geometry geometry
}
routes_to_pois {
int id PK
dateTime created_at
dateTime updated_at
int route_id FK
int poi_id FK
int visit_order
}
notifications {
int id PK
timestamp created_at
timestamp updated_at
int user_id FK
enum notification_type
enum entity_type
int entity_id
text content
timestamp read_at
}
files {
int id PK
dateTime created_at
dateTime updated_at
varchar url
varchar content_type
enum folder
int entity_id
}
user_routes {
int id PK
dateTime created_at
dateTime updated_at
int user_id FK
int route_id FK
enum status
dateTime started_at
dateTime completed_at
geometry planned_geometry
geometry actual_geometry
}
users }|--|| groups : group_id
groups ||--|{ groups_to_permissions : group_id
permissions ||--|{ groups_to_permissions : permission_id
users ||--|{ user_follows : follower_id
users ||--|{ user_follows : following_id
points_of_interest }|--|{routes_to_pois:"poi_id"
routes }|--|{routes_to_pois:"route_id"
users ||--|{ user_routes : user_id
routes ||--|{ user_routes : route_id
users ||--|{ reviews : user_id
routes ||--|{ reviews : route_id
routes ||--|{ route_categories : route_id
categories ||--|{ route_categories : category_id
points_of_interest ||--|{ reviews : poi_id
users ||--o{ notifications : user_id
TBD
- React — a frontend library
- Redux + Redux Toolkit — a state manager
-
assets - static assets (images, global styles)
-
libs - shared libraries and utilities
2.1. components - plain react components
2.2. enums
2.3. helpers
2.4. hooks
2.5. modules - separate features or functionalities
2.6. types
-
modules - separate app features or functionalities
-
pages - app pages
-
db - database data (migrations, seeds)
-
libs - shared libraries and utilities
2.1. enums
2.2. exceptions
2.3. helpers
2.4. modules - separate features or functionalities
2.5. types
-
modules - separate app features or functionalities
As we are already using js on both frontend and backend it would be useful to share some contracts and code between them.
- Zod — a schema validator
-
Copy and fill env files:
apps/frontend/.env
apps/backend/.env
tests/.env
(for integration tests)
You should use
.env.example
files as a reference. -
Install dependencies:
npm install
. -
Install pre-commit hooks:
npm run git:hooks:prepare
. Those hooks are used to verify code style on commit. -
Build shared:
npm run build:shared
-
Run database. You can run it by installing postgres on your computer.
-
Apply migrations:
npm run migrate:dev -w apps/backend
-
Run backend:
npm run start:dev -w apps/backend
-
Run frontend:
npm run start:dev -w apps/frontend
npm install
- Install all workspaces’ dependenciesnpm run git:hooks:prepare
- Set up pre-commit hooks
npm run lint
- Run all linting checksnpm run format
- Auto‑format the entire codebase with Prettier
npm run test:unit
- Run unit testsnpm run test:unit:coverage
- Run unit tests and generate a coverage reportnpm run test:integration
- Run integration tests
npm run migrate:dev -w apps/backend
- Apply all pending migrationsnpm run migrate:dev:make -w apps/backend -- <name>
- Create a new migration file (specify<name>
)npm run migrate:dev:down -w apps/backend
- Roll back the most recent migrationnpm run migrate:dev:rollback -w apps/backend
- Roll back all migrations
npm run start:dev -w apps/backend
- Start the backend in development mode (with auto‑reload)npm run start:dev -w apps/frontend
- Start the frontend in development mode
npm run build
- Build shared, backend, and frontend packagesnpm run start
- Run the production backend (from the build output)
For a full list of more specialized scripts (lint:js, lint:types, build:shared, lint:unused, etc.), see the scripts section of the corresponding package.json
.
We use Conventional Commits to handle commit messages.
<type>(<scope>): <subject> <issue-prefix><issue-number>
- type:
build
,chore
,ci
,docs
,feat
,fix
,perf
,refactor
,revert
,style
,test
- scope:
root
,release
,frontend
,backend
,shared
- subject: short description
- issue‑prefix:
ss-
,release-
- issue‑number: the number of the issue
Examples:
feat(frontend): add dashboard component ss-45
fix(shared/backend): update dashboard card size ss-212
chore(root): update eslint config ss-12
Important
- The scope field is required and must be one of the enums above.
- To target multiple scopes, join them with a slash, e.g.
frontend/shared
. - Every commit must reference an issue using the configured prefixes.
<issue-number>-<type>-<short-desc>
Examples:
123-feat-add-dashboard
12-feat-add-user-flow
34-fix-user-flow
Pull Request title should follow the same format as your commit messages.
<type>(<scope>): <subject> <issue-prefix><issue-number>
Examples:
feat(frontend): add dashboard component ss-45
We require unit tests for the backend code including:
- Controllers
- Services
- Repositories
- Entities
- Helpers
CI/CD implemented using GitHub Actions