v1.0.3
All checks were successful
Build and Push App Image / build-and-push (push) Successful in 59s
Notely - Secure Multi-Space Note-Taking Application
A production-ready, secure multi-tenant note-taking platform built with Go, Vue 3, and MongoDB.
🚀 Quick Start
Prerequisites
- Docker & Docker Compose
- Go 1.21+ (for local development)
- Node.js 18+ (for frontend development)
- MongoDB 7.0+ (for local development)
Development with Docker Compose
# Start all services
docker-compose up
# Backend: http://localhost:8080
# Frontend: http://localhost:5173
# MongoDB: localhost:27017
# Nginx: http://localhost:80
Local Development Setup
Backend
cd backend
# Install dependencies
go mod download
# Set environment variables
export MONGODB_URI=mongodb://admin:password@localhost:27017/noteapp?authSource=admin
export JWT_SECRET=your-secret-key
export ENCRYPTION_KEY=00000000000000000000000000000000
# Run migrations and server
go run ./cmd/server/main.go
Frontend
cd frontend
# Install dependencies
npm install
# Start development server
npm run dev
📚 Architecture
Backend (GoClean Architecture)
backend/
├── cmd/server/ # Entry point
├── internal/
│ ├── domain/ # Business logic (entities, interfaces)
│ ├── application/ # Use cases (services, DTOs)
│ ├── infrastructure/ # External dependencies (DB, auth)
│ └── interfaces/ # API handlers & middleware
├── pkg/ # Public packages
└── tests/ # Test suites
Frontend (Vue 3 Composition API)
frontend/
├── src/
│ ├── components/ # Reusable Vue components
│ ├── pages/ # Page components
│ ├── stores/ # Pinia state management
│ ├── services/ # API client
│ ├── router/ # Vue Router config
│ ├── assets/ # Styles and assets
│ └── main.js # Entry point
├── index.html
└── vite.config.js
🔐 Security Features
Authentication
- Argon2id password hashing - Industry-standard PBKDF2
- JWT tokens with short expiration (1 hour)
- HTTP-only secure cookies for refresh tokens
- CSRF protection via SameSite cookies
- Brute-force protection via login attempt tracking
Authorization
- Role-based access control (RBAC) per space:
- Owner: Full control
- Editor: Edit notes and categories
- Viewer: Read-only access
- Space-level data isolation - all queries include space_id
- IDOR prevention - middleware enforces ownership verification
Data Security
- Encryption at rest for sensitive fields (OAuth secrets)
- HTTPS/TLS in production (Nginx reverse proxy)
- Content Security Policy (CSP) headers
- XSS protection - DOMPurify for markdown sanitization
- SQL injection prevention - parameterized queries (MongoDB)
API Security
- Rate limiting - IP-based and user-based
- Security headers - HSTS, X-Frame-Options, X-Content-Type-Options
- CORS properly configured - whitelist origin domains
- Input validation on all endpoints
📦 API Endpoints
Authentication
POST /api/v1/auth/register - Register new user
POST /api/v1/auth/login - Login user
POST /api/v1/auth/refresh - Refresh access token
POST /api/v1/auth/logout - Logout user
GET /health - Health check
Spaces
GET /api/v1/spaces - List user's spaces
POST /api/v1/spaces - Create space
GET /api/v1/spaces/{spaceId} - Get space details
PUT /api/v1/spaces/{spaceId} - Update space
DELETE /api/v1/spaces/{spaceId} - Delete space
Notes
GET /api/v1/spaces/{spaceId}/notes - List notes
POST /api/v1/spaces/{spaceId}/notes - Create note
GET /api/v1/spaces/{spaceId}/notes/{noteId} - Get note
PUT /api/v1/spaces/{spaceId}/notes/{noteId} - Update note
DELETE /api/v1/spaces/{spaceId}/notes/{noteId} - Delete note
GET /api/v1/spaces/{spaceId}/notes/search?q= - Search notes
Categories
GET /api/v1/spaces/{spaceId}/categories - List categories
POST /api/v1/spaces/{spaceId}/categories - Create category
PUT /api/v1/spaces/{spaceId}/categories/{id} - Update category
DELETE /api/v1/spaces/{spaceId}/categories/{id} - Delete category
🗄️ Database Design
MongoDB Collections
users
{
_id: ObjectId,
email: String (unique),
username: String (unique),
password_hash: String,
first_name: String,
last_name: String,
avatar: String,
is_active: Boolean,
email_verified: Boolean,
created_at: Date,
updated_at: Date,
last_login_at: Date
}
spaces
{
_id: ObjectId,
name: String,
description: String,
icon: String,
owner_id: ObjectId,
is_public: Boolean,
created_at: Date,
updated_at: Date
}
memberships
{
_id: ObjectId,
user_id: ObjectId,
space_id: ObjectId,
role: String (owner|editor|viewer),
joined_at: Date,
invited_by: ObjectId,
invited_at: Date
}
notes
{
_id: ObjectId,
space_id: ObjectId,
category_id: ObjectId,
title: String,
content: String (Markdown),
tags: [String],
is_pinned: Boolean,
is_favorite: Boolean,
created_by: ObjectId,
updated_by: ObjectId,
created_at: Date,
updated_at: Date,
viewed_at: Date
}
categories
{
_id: ObjectId,
space_id: ObjectId,
name: String,
description: String,
parent_id: ObjectId (for hierarchical structure),
icon: String,
order: Number,
created_by: ObjectId,
updated_by: ObjectId,
created_at: Date,
updated_at: Date
}
Indexes
users: { email: 1 (unique), username: 1 (unique) }
spaces: { owner_id: 1, created_at: -1 }
memberships: { user_id: 1, space_id: 1 (unique), space_id: 1 }
notes: { space_id: 1, category_id: 1, updated_at: -1, text: "text" }
categories: { space_id: 1, parent_id: 1, order: 1 }
🐳 Deployment
Docker Compose (Development/Testing)
docker-compose up -d
Services:
- MongoDB (port 27017)
- Backend API (port 8080)
- Frontend (port 5173)
- Nginx Reverse Proxy (port 80)
Kubernetes (Production)
# Create namespace and secrets
kubectl apply -f devops/kubernetes/deployment.yaml
# Verify deployment
kubectl get pods -n noteapp
kubectl port-forward svc/frontend 5173:5173 -n noteapp
kubectl port-forward svc/backend 8080:8080 -n noteapp
Features:
- StatefulSet for MongoDB with persistent storage
- Deployments for backend and frontend with horizontal scaling
- Ingress for routing (requires ingress controller)
- HPA (Horizontal Pod Autoscaler) for automatic scaling
- Liveness & readiness probes for health checks
- Resource limits for fair resource allocation
🧪 Testing
Backend Tests
cd backend
go test ./...
go test -v ./tests/unit/...
go test -v ./tests/integration/...
Frontend Tests
cd frontend
npm run test
npm run test:watch
🔧 Configuration
Environment Variables
Backend (.env)
MONGODB_URI=mongodb://admin:password@localhost:27017/noteapp
JWT_SECRET=your-secret-key-min-32-chars
ENCRYPTION_KEY=32-char-encryption-key-for-secrets
PORT=8080
LOG_LEVEL=info
ENV=development
Frontend (.env)
VITE_API_BASE_URL=http://localhost:8080
📝 Development Guidelines
Code Structure
- Follow clean architecture principles
- Separate concerns: domain, application, infrastructure
- Use interfaces for dependency injection
- Keep services testable and focused
Security Best Practices
- Never store secrets in code - use environment variables
- Validate all inputs on backend
- Sanitize outputs before rendering
- Use HTTPS in production
- Implement rate limiting on APIs
- Log security events (login attempts, permission denied)
- Audit trail for sensitive operations
Commit Message Format
[TYPE] Description
types: feat, fix, docs, style, refactor, test, chore
📖 API Documentation
Request/Response Format
All API requests and responses use JSON.
# Example: Create Note
curl -X POST http://localhost:8080/api/v1/spaces/{spaceId}/notes \
-H "Authorization: Bearer {accessToken}" \
-H "Content-Type: application/json" \
-d '{
"title": "My Note",
"content": "# Markdown content",
"tags": ["tag1", "tag2"],
"category_id": null,
"is_pinned": false,
"is_favorite": false
}'
🚨 Error Handling
All errors return appropriate HTTP status codes:
400- Bad Request401- Unauthorized403- Forbidden (insufficient permissions)404- Not Found409- Conflict (e.g., duplicate email)429- Too Many Requests (rate limit exceeded)500- Internal Server Error
🎯 Future Enhancements
- OAuth2/OIDC integration
- Email notifications
- Real-time collaboration (WebSockets)
- Full-text search with Elasticsearch
- Export to PDF/Markdown
- Mobile applications
- Plugin system
- Advanced permissions management
📄 License
MIT License - See LICENSE file
👥 Contributing
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
Built with ❤️ for secure, collaborative note-taking
Description
Languages
Go
46.3%
Vue
41.7%
CSS
7.2%
JavaScript
4.7%