641 lines
17 KiB
Markdown
641 lines
17 KiB
Markdown
# Looking - PfosiLooking Monorepo
|
|
|
|
> **An art project exploring modern gay dating culture through interactive storytelling**
|
|
|
|
"Looking" is a documentary photography and art project by Nick Pfosi that examines the cultural landscape of gay dating apps like Grindr and modern LGBTQ+ meeting spaces. The project captures user stories, experiences, and narratives about contemporary gay dating culture through an interactive mobile application.
|
|
|
|
---
|
|
|
|
## 📋 Table of Contents
|
|
|
|
- [Project Overview](#project-overview)
|
|
- [Tech Stack](#tech-stack)
|
|
- [Prerequisites](#prerequisites)
|
|
- [Quick Start](#quick-start)
|
|
- [Project Structure](#project-structure)
|
|
- [Available Scripts](#available-scripts)
|
|
- [Data Management](#data-management)
|
|
- [Documentation Links](#documentation-links)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Technical Debt & Security](#technical-debt--security)
|
|
- [Future Modernization Path](#future-modernization-path)
|
|
|
|
---
|
|
|
|
## 🎨 Project Overview
|
|
|
|
This monorepo contains the full-stack "Looking" application:
|
|
|
|
- **Frontend**: Ionic 3 / Angular 5 mobile application for browsing profiles and stories
|
|
- **Backend**: Express.js REST API with MongoDB for data management
|
|
- **DevContainer**: Complete Docker-based development environment
|
|
|
|
The name "Urnings" (seen in code) references a historical term for homosexual men, adding a scholarly dimension to the project's exploration of queer identity and dating culture.
|
|
|
|
---
|
|
|
|
## 🛠 Tech Stack
|
|
|
|
### Frontend ([app/](app/))
|
|
|
|
- **Framework**: Ionic 3.9.2 with Angular 5.0.3
|
|
- **Language**: TypeScript 2.4.2
|
|
- **Build Tool**: `@ionic/app-scripts` 3.2.4
|
|
- **UI Components**: Ionic Angular, Ionicons
|
|
- **HTTP**: Angular HTTP module with RxJS 5.5.2
|
|
- **Dev Server**: Port 8100
|
|
|
|
### Backend ([backend/](backend/))
|
|
|
|
- **Framework**: Express 4.14.0
|
|
- **Runtime**: Node.js 14.x
|
|
- **Database**: MongoDB 4.4
|
|
- **ODM**: Mongoose 4.7.4
|
|
- **Authentication**: JWT (jsonwebtoken 7.3.0)
|
|
- **Security**: PBKDF2 password hashing (233,335 iterations)
|
|
- **Image Processing**: Multer 1.2.0
|
|
- **Logging**: Winston 2.4.0, Morgan 1.7.0
|
|
- **Email**: Nodemailer 4.0.1
|
|
- **API Server**: Port 3069
|
|
|
|
### DevOps
|
|
|
|
- **DevContainer**: Node 14 (Debian Bullseye)
|
|
- **Database**: MongoDB 4.4
|
|
- **Database Admin**: Mongo Express (port 8081)
|
|
- **Production**: Docker Compose + Traefik + Let's Encrypt SSL
|
|
|
|
---
|
|
|
|
## ✅ Prerequisites
|
|
|
|
Before you begin, ensure you have:
|
|
|
|
- **Docker Desktop** (latest version) - [Download here](https://www.docker.com/products/docker-desktop)
|
|
- **Visual Studio Code** (latest version) - [Download here](https://code.visualstudio.com/)
|
|
- **VS Code Remote - Containers extension** - [Install from marketplace](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
|
|
- **Git** (for cloning the repository)
|
|
|
|
> **Note**: You do NOT need Node.js, npm, or MongoDB installed locally. The DevContainer provides everything.
|
|
|
|
---
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### Using DevContainer (Recommended)
|
|
|
|
1. **Clone the repository**:
|
|
|
|
```bash
|
|
git clone <repository-url>
|
|
cd PfosiLooking-monorepo
|
|
```
|
|
|
|
2. **Open in VS Code**:
|
|
|
|
```bash
|
|
code .
|
|
```
|
|
|
|
3. **Reopen in Container**:
|
|
|
|
- VS Code should prompt: "Reopen in Container"
|
|
- Or manually: Press `F1` → "Dev Containers: Reopen in Container"
|
|
|
|
4. **Wait for setup** (first time only - 5-10 minutes):
|
|
|
|
- Container builds with Node 14 + Python 2.7
|
|
- Dependencies install automatically via `postCreateCommand.sh`
|
|
- MongoDB starts and initializes
|
|
|
|
5. **Start development servers**:
|
|
|
|
```bash
|
|
npm run dev:all
|
|
```
|
|
|
|
6. **Access the application**:
|
|
- **Frontend**: http://localhost:8100
|
|
- **Backend API**: http://localhost:3069
|
|
- **MongoDB**: localhost:27017
|
|
- **Mongo Express**: http://localhost:8081 (admin/password)
|
|
|
|
---
|
|
|
|
## 📁 Project Structure
|
|
|
|
```
|
|
PfosiLooking-monorepo/
|
|
├── app/ # Ionic 3 / Angular 5 frontend
|
|
│ ├── src/
|
|
│ │ ├── app/ # App module and root component
|
|
│ │ ├── pages/ # Page components (grid, chat, profile, etc.)
|
|
│ │ ├── services/ # Data services (ProfileService)
|
|
│ │ └── assets/ # Static assets, images, data
|
|
│ └── package.json # Frontend dependencies
|
|
│
|
|
├── backend/ # Express.js API
|
|
│ ├── src/
|
|
│ │ ├── routes/ # API route handlers
|
|
│ │ ├── models/ # Mongoose schemas
|
|
│ │ ├── modules/ # Utilities (auth, images, mailer, etc.)
|
|
│ │ └── bin/www # Server startup script
|
|
│ ├── data/ # Seed data (profiles.json)
|
|
│ └── package.json # Backend dependencies
|
|
│
|
|
├── .devcontainer/ # Development container configuration
|
|
│ ├── devcontainer.json # VS Code DevContainer config
|
|
│ ├── docker-compose.yml # Dev services (app, mongo, mongo-express)
|
|
│ ├── Dockerfile # Custom dev image (Node 14 + Python 2.7)
|
|
│ └── postCreateCommand.sh # Auto-install dependencies
|
|
│
|
|
├── docker-compose.yml # Production deployment configuration
|
|
├── package.json # Root workspace configuration
|
|
└── README.md # This file
|
|
```
|
|
|
|
---
|
|
|
|
## 📜 Available Scripts
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Start both frontend and backend concurrently
|
|
npm run dev:all
|
|
|
|
# Start only backend (port 3069)
|
|
npm run dev:backend
|
|
|
|
# Start only frontend (port 8100)
|
|
npm run dev:app
|
|
```
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
# Install all dependencies (root + workspaces)
|
|
npm run install:all
|
|
|
|
# Install workspace dependencies only
|
|
npm run install:workspaces
|
|
```
|
|
|
|
### Database
|
|
|
|
```bash
|
|
# Seed MongoDB with initial data from backend/data/profiles.json
|
|
npm run seed
|
|
|
|
# Access MongoDB shell
|
|
npm run mongo:shell
|
|
```
|
|
|
|
### Build & Deploy
|
|
|
|
```bash
|
|
# Build both frontend and backend
|
|
npm run build
|
|
|
|
# Build Docker images for production
|
|
npm run docker:build
|
|
|
|
# Deploy to production (docker-compose up)
|
|
npm run deploy
|
|
```
|
|
|
|
### Testing & Quality
|
|
|
|
```bash
|
|
# Run all tests (backend + frontend)
|
|
npm test
|
|
|
|
# Run backend tests only (Mocha/Chai)
|
|
npm run test:backend
|
|
|
|
# Run frontend tests only
|
|
npm run test:app
|
|
|
|
# Lint all code
|
|
npm run lint
|
|
```
|
|
|
|
---
|
|
|
|
## 💾 Data Management
|
|
|
|
### ⚠️ Important: No Interactive Data Entry
|
|
|
|
**This application currently does NOT support adding or editing data through the UI.** All profile and message data is seeded from static JSON files.
|
|
|
|
### How to Add/Edit Content
|
|
|
|
1. **Edit the seed data file**: [`backend/data/profiles.json`](backend/data/profiles.json)
|
|
|
|
2. **Re-seed the database**:
|
|
|
|
```bash
|
|
npm run seed
|
|
```
|
|
|
|
3. **For production deployments**: The database is wiped and reseeded on each deployment, so all changes must be committed to `profiles.json` before deploying.
|
|
|
|
### Data Structure
|
|
|
|
Profiles are stored in `backend/data/profiles.json` with this structure:
|
|
|
|
```json
|
|
{
|
|
"order": 1,
|
|
"details": {
|
|
"name": "John",
|
|
"age": 28,
|
|
"location": "San Francisco, CA",
|
|
"about": "User's story...",
|
|
"pic": {
|
|
"thumb": "profile/john_thumbnail.png",
|
|
"detail": "profile/john_detail.png"
|
|
}
|
|
},
|
|
"messages": [
|
|
{
|
|
"text": "What's your story?",
|
|
"isUser": false
|
|
},
|
|
{
|
|
"text": "I've been using dating apps for...",
|
|
"isUser": true
|
|
}
|
|
],
|
|
"submitted": true,
|
|
"approved": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Documentation Links
|
|
|
|
- **[App Documentation](app/README.md)** - Frontend architecture, pages, and services
|
|
- **[Backend Documentation](backend/README.md)** - API server, routes, and models
|
|
- **[API Reference](backend/API.md)** - Complete REST API endpoint documentation
|
|
- **[Database Schema](backend/SCHEMA.md)** - MongoDB collection schemas and relationships
|
|
- **[DevContainer Guide](.devcontainer/README.md)** - Development environment setup
|
|
- **[Deployment Guide](DEPLOYMENT.md)** - Production deployment with Docker and Traefik
|
|
|
|
---
|
|
|
|
## 🔧 Troubleshooting
|
|
|
|
### DevContainer Issues
|
|
|
|
**Problem**: Container fails to start or build
|
|
|
|
```bash
|
|
# Solution: Rebuild container without cache
|
|
F1 → "Dev Containers: Rebuild Container Without Cache"
|
|
```
|
|
|
|
**Problem**: Port conflicts (8100, 3069, 27017, 8081 already in use)
|
|
|
|
```bash
|
|
# Solution: Stop conflicting services
|
|
docker ps # Find conflicting containers
|
|
docker stop <container-id>
|
|
|
|
# Or change ports in .devcontainer/docker-compose.yml
|
|
```
|
|
|
|
**Problem**: `node_modules` issues or permission errors
|
|
|
|
```bash
|
|
# Solution: Remove node_modules and reinstall
|
|
rm -rf app/node_modules backend/node_modules node_modules
|
|
npm run install:all
|
|
```
|
|
|
|
### Frontend Issues
|
|
|
|
**Problem**: `node-sass` build failed
|
|
|
|
```bash
|
|
# Solution: Python 2.7 is required (included in DevContainer)
|
|
# If running locally without DevContainer:
|
|
npm install --legacy-peer-deps
|
|
```
|
|
|
|
**Problem**: Peer dependency warnings during `npm install`
|
|
|
|
```bash
|
|
# Solution: Use legacy peer deps flag (included in postCreateCommand.sh)
|
|
cd app
|
|
npm install --legacy-peer-deps
|
|
```
|
|
|
|
**Problem**: Module not found errors
|
|
|
|
```bash
|
|
# Solution: Clear cache and reinstall
|
|
cd app
|
|
rm -rf node_modules package-lock.json
|
|
npm install --legacy-peer-deps
|
|
```
|
|
|
|
**Problem**: JavaScript heap out of memory
|
|
|
|
```bash
|
|
# Solution: Increase Node.js memory limit
|
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
npm run dev:app
|
|
```
|
|
|
|
### Backend Issues
|
|
|
|
**Problem**: MongoDB connection failed
|
|
|
|
```bash
|
|
# Solution: Verify MongoDB container is running
|
|
docker ps | grep mongo
|
|
|
|
# Check MongoDB health
|
|
docker exec -it <mongo-container-id> mongo --eval "db.adminCommand('ping')"
|
|
|
|
# Restart MongoDB service
|
|
docker-compose -f .devcontainer/docker-compose.yml restart mongo
|
|
```
|
|
|
|
**Problem**: JWT token invalid errors
|
|
|
|
```bash
|
|
# Solution: Verify JWT_SECRET is set in .devcontainer/dev.env
|
|
# Check backend/.env.example for required environment variables
|
|
```
|
|
|
|
**Problem**: Image upload fails
|
|
|
|
```bash
|
|
# Solution: Check volume permissions and multer configuration
|
|
# Verify backend/src/images directory exists and is writable
|
|
ls -la backend/src/images
|
|
```
|
|
|
|
**Problem**: Cannot connect to API from frontend
|
|
|
|
```bash
|
|
# Solution: Verify backend is running on port 3069
|
|
curl http://localhost:3069/profiles
|
|
|
|
# Check CORS settings in backend/src/app.js
|
|
```
|
|
|
|
### Database Issues
|
|
|
|
**Problem**: Seed data not loading
|
|
|
|
```bash
|
|
# Solution: Manually run seed script
|
|
cd backend
|
|
npm run seed
|
|
|
|
# Or check data file exists
|
|
ls -la backend/data/profiles.json
|
|
```
|
|
|
|
**Problem**: Mongo Express not accessible
|
|
|
|
```bash
|
|
# Solution: Verify service is running and credentials are correct
|
|
# Default: http://localhost:8081 (admin/password)
|
|
docker logs <mongo-express-container-id>
|
|
```
|
|
|
|
---
|
|
|
|
## ⚠️ Technical Debt & Security
|
|
|
|
### Outdated Dependencies
|
|
|
|
This project uses **legacy technologies** (circa 2017-2018) that are significantly outdated:
|
|
|
|
| Component | Current Version | Latest Stable | Status |
|
|
| ------------ | --------------- | ------------- | --------------------------- |
|
|
| **Node.js** | 14.x | 20.x LTS | ⛔ EOL April 2023 |
|
|
| **Angular** | 5.0.3 | 17.x | ⛔ 12 major versions behind |
|
|
| **Ionic** | 3.9.2 | 7.x | ⛔ 4 major versions behind |
|
|
| **Express** | 4.14.0 | 4.18.x | ⚠️ Missing security patches |
|
|
| **MongoDB** | 4.4 | 7.0 | ⚠️ 3 major versions behind |
|
|
| **Mongoose** | 4.7.4 | 8.x | ⛔ 4 major versions behind |
|
|
|
|
### Security Concerns
|
|
|
|
1. **CORS Configuration**: Wide open (`Access-Control-Allow-Origin: *`)
|
|
|
|
- **Risk**: Any domain can make requests to API
|
|
- **Fix**: Restrict to specific origins in production (already configured in docker-compose.yml)
|
|
|
|
2. **No Rate Limiting**: API has no request throttling
|
|
|
|
- **Risk**: Vulnerable to brute force and DoS attacks
|
|
- **Fix**: Add `express-rate-limit` middleware
|
|
|
|
3. **Missing Input Validation**: No validation library
|
|
|
|
- **Risk**: Potential injection attacks
|
|
- **Fix**: Add Joi or express-validator
|
|
|
|
4. **JWT Secret Management**: Secret must be set via environment variable
|
|
|
|
- **Risk**: If leaked, tokens can be forged
|
|
- **Fix**: Use strong secrets, rotate regularly, consider refresh tokens
|
|
|
|
5. **Image Upload Security**: No file type/size restrictions visible
|
|
|
|
- **Risk**: Malicious file uploads
|
|
- **Fix**: Validate MIME types, set size limits, sanitize filenames
|
|
|
|
6. **Node.js 14 EOL**: No longer receives security updates
|
|
- **Risk**: Unpatched vulnerabilities
|
|
- **Fix**: Upgrade to Node 20 LTS (see modernization path below)
|
|
|
|
### Code Quality Issues
|
|
|
|
- No TypeScript in backend (JavaScript only)
|
|
- Limited test coverage (backend has Mocha tests, frontend has none)
|
|
- No automated CI/CD pipeline
|
|
- `ionic-app-scripts` is deprecated
|
|
- Gulp is dated for task running
|
|
|
|
---
|
|
|
|
## 🚀 Future Modernization Path
|
|
|
|
For developers tasked with modernizing this codebase, follow this **incremental upgrade strategy**:
|
|
|
|
### Phase 1: Critical Security Updates (2-4 weeks)
|
|
|
|
1. **Upgrade Node.js**:
|
|
|
|
```bash
|
|
# Update Dockerfile to use Node 20 LTS
|
|
FROM node:20-bullseye
|
|
|
|
# Remove Python 2.7 symlinks (modern node-sass doesn't need it)
|
|
```
|
|
|
|
2. **Update Backend Dependencies**:
|
|
|
|
```bash
|
|
cd backend
|
|
npm update express mongoose jsonwebtoken
|
|
npm install express-rate-limit express-validator helmet
|
|
```
|
|
|
|
3. **Add Security Middleware**:
|
|
|
|
```javascript
|
|
// backend/src/app.js
|
|
const rateLimit = require("express-rate-limit");
|
|
const helmet = require("helmet");
|
|
const { body, validationResult } = require("express-validator");
|
|
|
|
app.use(helmet());
|
|
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
|
|
```
|
|
|
|
4. **Fix CORS** (already done in production docker-compose.yml):
|
|
```javascript
|
|
// Restrict to specific origin
|
|
res.header("Access-Control-Allow-Origin", "https://pfosi.mifi.dev");
|
|
```
|
|
|
|
### Phase 2: Backend Modernization (4-6 weeks)
|
|
|
|
1. **Convert Backend to TypeScript**:
|
|
|
|
```bash
|
|
npm install -D typescript @types/express @types/node @types/mongoose
|
|
npx tsc --init
|
|
# Incrementally convert .js files to .ts
|
|
```
|
|
|
|
2. **Upgrade MongoDB & Mongoose**:
|
|
|
|
```bash
|
|
# Update docker-compose.yml
|
|
mongo:
|
|
image: mongo:7.0
|
|
|
|
# Update Mongoose
|
|
npm install mongoose@latest
|
|
```
|
|
|
|
3. **Modern Testing Setup**:
|
|
|
|
```bash
|
|
npm install -D jest ts-jest @types/jest supertest
|
|
# Migrate from Mocha/Chai to Jest
|
|
```
|
|
|
|
4. **Add API Documentation**:
|
|
```bash
|
|
npm install swagger-jsdoc swagger-ui-express
|
|
# Generate OpenAPI/Swagger docs from code
|
|
```
|
|
|
|
### Phase 3: Frontend Modernization (8-12 weeks)
|
|
|
|
This is the **most complex** phase due to breaking changes.
|
|
|
|
**Option A: Incremental Angular Upgrade** (Slower but safer)
|
|
|
|
```bash
|
|
# Upgrade through each major version
|
|
ng update @angular/cli@6 @angular/core@6
|
|
ng update @angular/cli@7 @angular/core@7
|
|
# ... continue through each version to 17
|
|
```
|
|
|
|
**Option B: Fresh Ionic 7 Rewrite** (Faster, cleaner)
|
|
|
|
```bash
|
|
# Create new Ionic 7 app with Angular 17
|
|
ionic start looking-v2 tabs --type=angular
|
|
# Port components one by one
|
|
# Benefits: Standalone components, Signals, better performance
|
|
```
|
|
|
|
**Recommendation**: For novice developers, **Option B (rewrite)** is recommended because:
|
|
|
|
- Angular 5 → 17 migration is complex with many breaking changes
|
|
- Ionic 3 → 7 requires complete UI component rewrites
|
|
- Fresh start allows modern architecture (standalone components, no NgModules)
|
|
- Cleaner codebase without legacy workarounds
|
|
|
|
### Phase 4: Modern Build Pipeline (2-3 weeks)
|
|
|
|
1. **Replace deprecated build tools**:
|
|
|
|
```bash
|
|
# Remove ionic-app-scripts, use Angular CLI
|
|
# Remove Gulp, use npm scripts
|
|
```
|
|
|
|
2. **Add CI/CD**:
|
|
|
|
```yaml
|
|
# .github/workflows/ci.yml or .gitlab-ci.yml
|
|
- Run tests on every commit
|
|
- Automated Docker builds
|
|
- Deployment to staging/production
|
|
```
|
|
|
|
3. **Code Quality Tools**:
|
|
```bash
|
|
npm install -D eslint prettier husky lint-staged
|
|
# Pre-commit hooks for linting
|
|
```
|
|
|
|
### Estimated Total Effort
|
|
|
|
- **Phase 1 (Security)**: 2-4 weeks - **START HERE**
|
|
- **Phase 2 (Backend)**: 4-6 weeks
|
|
- **Phase 3 (Frontend)**: 8-12 weeks - **Most complex**
|
|
- **Phase 4 (DevOps)**: 2-3 weeks
|
|
|
|
**Total**: 16-25 weeks (4-6 months) for full modernization
|
|
|
|
### Resources for Learning
|
|
|
|
- [Angular Update Guide](https://update.angular.io/) - Step-by-step migration instructions
|
|
- [Ionic Migration Guide](https://ionicframework.com/docs/intro/upgrading-to-ionic-7)
|
|
- [Node.js Best Practices](https://github.com/goldbergyoni/nodebestpractices)
|
|
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
|
|
|
|
---
|
|
|
|
## 🤝 Contributing
|
|
|
|
This is an art project with specific artistic intent. Before making changes:
|
|
|
|
1. Understand the artistic and documentary purpose
|
|
2. Preserve the original narrative and user stories
|
|
3. Consult with the artist (Nick Pfosi) for content changes
|
|
4. Follow the modernization path for technical improvements
|
|
|
|
---
|
|
|
|
## 📄 License
|
|
|
|
See project repository for license information.
|
|
|
|
---
|
|
|
|
## 👤 Author
|
|
|
|
**Nick Pfosi** - Artist & Creator
|
|
**Mike Fitzpatrick** - Technical Implementation (badmf@mifi.dev)
|
|
|
|
---
|
|
|
|
**Questions or Issues?** Check the [troubleshooting section](#troubleshooting) or refer to component-specific documentation linked above.
|