A comprehensive backend platform with AI-powered recommendations, user management, content moderation, and administrative dashboard.
Atlas is a production-ready backend platform that combines modern authentication, AI-powered recommendations, comprehensive content management, and a full-featured admin dashboard. Built with TypeScript, Express.js, and MongoDB, it provides everything needed for a scalable web application backend.
- π JWT Authentication - Secure user registration, login, and token management
- π€ AI Recommendations - Intelligent content recommendations based on user interests
- π Admin Dashboard - Complete administrative interface with analytics and user management
- π‘οΈ Role-Based Access - User, moderator, and admin role management
- π Content Management - Full CRUD operations for events, organizations, and labs
- π Analytics & Reporting - Detailed system analytics with data export capabilities
- π Advanced Search - Flexible search and filtering across all content types
- β‘ Performance Optimized - Efficient MongoDB queries and response caching
Atlas Backend Platform
βββ π Authentication Module
β βββ JWT Token Management
β βββ Password Hashing (bcrypt)
β βββ Role-Based Access Control
βββ π€ AI Recommendations Engine
β βββ Interest-Based Matching
β βββ Content Scoring Algorithm
β βββ Dynamic Recommendation Updates
βββ π Content Management System
β βββ Events Management
β βββ Organizations Directory
β βββ Labs & Projects Hub
βββ ποΈ Admin Dashboard Backend
β βββ User Management & Analytics
β βββ Content Moderation System
β βββ System Health Monitoring
β βββ Data Export & Reporting
βββ π REST API Layer
βββ Express.js Server
βββ Middleware Stack
βββ Error Handling System
- Node.js v16.0.0 or higher
- MongoDB v4.4 or higher
- npm or yarn package manager
-
Clone the repository:
git clone https://github.com/your-username/atlas.git cd atlas -
Install dependencies:
npm install
-
Environment Setup:
cp .env.example .env
Configure your
.envfile:# Server Configuration PORT=3001 NODE_ENV=development # Database MONGODB_URI=mongodb://localhost:27017/atlas # JWT Configuration JWT_SECRET=your-super-secret-jwt-key JWT_EXPIRES_IN=24h JWT_REFRESH_SECRET=your-refresh-secret-key JWT_REFRESH_EXPIRES_IN=7d # Admin Configuration ADMIN_SESSION_TIMEOUT=3600000 ADMIN_MAX_LOGIN_ATTEMPTS=5 # Features RECOMMENDATIONS_ENABLED=true ANALYTICS_ENABLED=true
-
Start MongoDB:
# Using MongoDB service sudo systemctl start mongod # Or using Docker docker run -d -p 27017:27017 --name atlas-mongo mongo:latest
-
Run the application:
# Development mode with hot reload npm run dev # Production mode npm run build npm start
-
Verify installation:
curl http://localhost:3001/api/health
atlas/
βββ src/backend/
β βββ modules/
β β βββ api/
β β β βββ routes/
β β β β βββ auth/ # Authentication routes
β β β β βββ users/ # User management routes
β β β β βββ events/ # Events CRUD routes
β β β β βββ organizations/ # Organizations routes
β β β β βββ labs/ # Labs routes
β β β β βββ recommendations/ # AI recommendations
β β β β βββ admin/ # Admin dashboard routes
β β β β βββ dashboard.ts
β β β β βββ users.ts
β β β β βββ content.ts
β β β β βββ analytics.ts
β β β β βββ middleware.ts
β β β βββ index.ts # API routes aggregator
β β βββ database/
β β β βββ models/ # MongoDB schemas
β β β β βββ User.ts
β β β β βββ Event.ts
β β β β βββ Organization.ts
β β β β βββ Lab.ts
β β β βββ connection.ts # Database connection
β β βββ auth/
β β β βββ middleware.ts # JWT middleware
β β β βββ utils.ts # Auth utilities
β β βββ recommendations/
β β βββ engine.ts # AI recommendation engine
β βββ middleware/ # Global middleware
β βββ types/ # TypeScript type definitions
β βββ utils/ # Utility functions
βββ server.ts # Express server setup
βββ package.json
βββ tsconfig.json
βββ README.md # This file
βββ ADMIN-DASHBOARD.md # Admin documentation
// Register new user
POST /auth/register
{
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"password": "securePassword123",
"interests": [1, 2, 3]
}
// User login
POST /auth/login
{
"username": "johndoe",
"password": "securePassword123"
}
// Refresh JWT token
POST /auth/refresh
{
"refreshToken": "your_refresh_token_here"
}
// Get current user profile
GET /auth/profile
Authorization: Bearer <your_jwt_token>// Get all users (paginated)
GET /users?page=1&limit=20&search=john
// Get user by ID
GET /users/:id
// Update user profile
PUT /users/:id
Authorization: Bearer <jwt_token>
// Delete user account
DELETE /users/:id
Authorization: Bearer <jwt_token>// Get all events
GET /events?page=1&limit=20&search=hackathon&location=NYC
// Create new event
POST /events
Authorization: Bearer <jwt_token>
{
"title": "Tech Conference 2024",
"description": "Annual technology conference",
"date": "2024-06-15",
"location": "New York City",
"organizer": "Tech Corp"
}
// Get event by ID
GET /events/:id
// Update event
PUT /events/:id
Authorization: Bearer <jwt_token>
// Delete event
DELETE /events/:id
Authorization: Bearer <jwt_token>// Get all organizations
GET /organizations?page=1&limit=20&search=tech&type=startup
// Create organization
POST /organizations
Authorization: Bearer <jwt_token>
{
"name": "Tech Innovators Inc",
"description": "Leading technology innovation company",
"type": "startup",
"location": "San Francisco",
"website": "https://techinnovators.com"
}
// Organization CRUD operations
GET /organizations/:id
PUT /organizations/:id
DELETE /organizations/:id// Get all labs
GET /labs?page=1&limit=20&search=AI&field=machine-learning
// Create lab/project
POST /labs
Authorization: Bearer <jwt_token>
{
"name": "AI Research Lab",
"description": "Cutting-edge artificial intelligence research",
"field": "machine-learning",
"leader": "Dr. Sarah Johnson",
"status": "active"
}
// Lab CRUD operations
GET /labs/:id
PUT /labs/:id
DELETE /labs/:id// Get personalized recommendations
GET /recommendations
Authorization: Bearer <jwt_token>
Query params: ?type=events&limit=10&includeScore=true
// Get recommendations for specific user
GET /recommendations/user/:userId
Authorization: Bearer <admin_jwt_token>
// Update user interests (affects future recommendations)
PUT /recommendations/interests
Authorization: Bearer <jwt_token>
{
"interests": [1, 2, 5, 8]
}All admin endpoints require Authorization: Bearer <admin_jwt_token>
// System overview
GET /admin/dashboard
// User management
GET /admin/users?page=1&limit=20&role=admin
PUT /admin/users/:id/role { "role": "moderator" }
// Content moderation
GET /admin/content/pending?type=events
PUT /admin/content/events/:id/approve
PUT /admin/content/events/:id/reject { "reason": "Inappropriate content" }
// Analytics & reporting
GET /admin/analytics/overview?period=30
GET /admin/analytics/users
GET /admin/analytics/export?format=json&type=overviewThe Atlas recommendation engine uses an intelligent matching algorithm to provide personalized content suggestions based on user interests and behavior patterns.
- Interest Profiling: Users select interests during registration
- Content Scoring: Each content item is scored against user interests
- Dynamic Ranking: Recommendations are ranked by relevance score
- Continuous Learning: System adapts based on user interactions
// Simplified scoring algorithm
function calculateRecommendationScore(content: Content, userInterests: number[]): number {
const baseScore = 50; // Base relevance score
const interestBonus = content.interests?.reduce((score, interest) => {
return userInterests.includes(interest) ? score + 25 : score;
}, 0) || 0;
// Additional factors
const recencyBonus = calculateRecencyBonus(content.createdAt);
const popularityBonus = calculatePopularityBonus(content.views || 0);
return Math.min(100, baseScore + interestBonus + recencyBonus + popularityBonus);
}// Get personalized event recommendations
const eventRecommendations = await fetch('/api/recommendations?type=events&limit=5', {
headers: { 'Authorization': `Bearer ${userToken}` }
});
// Get mixed content recommendations with scores
const allRecommendations = await fetch('/api/recommendations?limit=10&includeScore=true', {
headers: { 'Authorization': `Bearer ${userToken}` }
});
// Update user interests to improve recommendations
await fetch('/api/recommendations/interests', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${userToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ interests: [1, 3, 7, 12] })
});Atlas includes a comprehensive admin dashboard backend for complete system management. See ADMIN-DASHBOARD.md for detailed documentation.
- π System Overview: Real-time system health, performance metrics, and usage statistics
- π₯ User Management: Complete user lifecycle management with role-based access control
- π Content Moderation: Approval workflows for events, organizations, and labs
- π Analytics & Reporting: Detailed system analytics with CSV/JSON export capabilities
- π Advanced Search: Powerful search and filtering across all system entities
- π‘οΈ Security Management: Session tracking, activity logging, and access control
# 1. Create admin user in MongoDB
mongosh atlas
db.users.updateOne(
{ username: 'your_username' },
{ $set: { role: 'admin' } }
)
# 2. Login and access admin endpoints
curl -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin_user","password":"admin_password"}'
# 3. Use admin token for dashboard access
curl -H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:3001/api/admin/dashboardinterface User {
userId: number; // Auto-increment primary key
name: string; // Full name
username: string; // Unique username
email: string; // Unique email address
password: string; // Hashed password
role: 'user' | 'admin' | 'moderator'; // User role
interests: number[]; // Array of interest IDs
createdAt: Date; // Registration timestamp
updatedAt: Date; // Last update timestamp
lastLogin?: Date; // Last login timestamp
}interface Event {
id: string; // MongoDB ObjectId
title: string; // Event title
description?: string; // Event description
date: Date; // Event date
location?: string; // Event location
organizer?: string; // Event organizer
interests?: number[]; // Related interest IDs
createdBy: number; // User ID of creator
createdAt: Date; // Creation timestamp
updatedAt: Date; // Last update timestamp
views?: number; // View count for popularity
}interface Organization {
id: string; // MongoDB ObjectId
name: string; // Organization name
description?: string; // Organization description
type?: string; // Organization type
location?: string; // Organization location
website?: string; // Organization website
interests?: number[]; // Related interest IDs
createdBy: number; // User ID of creator
createdAt: Date; // Creation timestamp
updatedAt: Date; // Last update timestamp
views?: number; // View count for popularity
}interface Lab {
id: string; // MongoDB ObjectId
name: string; // Lab name
description?: string; // Lab description
field?: string; // Research field
leader?: string; // Lab leader
status?: string; // Lab status
interests?: number[]; // Related interest IDs
createdBy: number; // User ID of creator
createdAt: Date; // Creation timestamp
updatedAt: Date; // Last update timestamp
views?: number; // View count for popularity
}# Server Configuration
PORT=3001 # Server port
NODE_ENV=development # Environment mode
CORS_ORIGIN=http://localhost:3000 # CORS allowed origin
# Database Configuration
MONGODB_URI=mongodb://localhost:27017/atlas # MongoDB connection string
MONGODB_OPTIONS={} # Additional MongoDB options
# JWT Authentication
JWT_SECRET=your-256-bit-secret # JWT signing secret (use strong secret!)
JWT_EXPIRES_IN=24h # Access token expiration
JWT_REFRESH_SECRET=refresh-secret # Refresh token secret
JWT_REFRESH_EXPIRES_IN=7d # Refresh token expiration
# Security Settings
BCRYPT_ROUNDS=12 # Password hashing rounds
RATE_LIMIT_WINDOW=900000 # Rate limit window (15 min)
RATE_LIMIT_MAX=100 # Max requests per window
# Feature Flags
RECOMMENDATIONS_ENABLED=true # Enable AI recommendations
ANALYTICS_ENABLED=true # Enable analytics collection
ADMIN_DASHBOARD_ENABLED=true # Enable admin dashboard
# Admin Configuration
ADMIN_SESSION_TIMEOUT=3600000 # Admin session timeout (1 hour)
ADMIN_MAX_LOGIN_ATTEMPTS=5 # Max failed login attempts
ADMIN_LOCKOUT_DURATION=1800000 # Account lockout duration (30 min)
# Analytics Configuration
ANALYTICS_RETENTION_DAYS=90 # Data retention period
ANALYTICS_EXPORT_MAX_ROWS=10000 # Max rows for data export
ANALYTICS_CACHE_TTL=300000 # Cache TTL (5 minutes)
# Logging
LOG_LEVEL=info # Logging level
LOG_FILE=logs/atlas.log # Log file pathFor optimal performance, create these indexes:
// User indexes
db.users.createIndex({ "username": 1 }, { unique: true });
db.users.createIndex({ "email": 1 }, { unique: true });
db.users.createIndex({ "userId": 1 }, { unique: true });
db.users.createIndex({ "role": 1 });
db.users.createIndex({ "interests": 1 });
db.users.createIndex({ "createdAt": -1 });
// Content indexes
db.events.createIndex({ "title": "text", "description": "text" });
db.events.createIndex({ "date": 1 });
db.events.createIndex({ "createdAt": -1 });
db.events.createIndex({ "interests": 1 });
db.organizations.createIndex({ "name": "text", "description": "text" });
db.organizations.createIndex({ "type": 1 });
db.organizations.createIndex({ "location": 1 });
db.organizations.createIndex({ "createdAt": -1 });
db.labs.createIndex({ "name": "text", "description": "text" });
db.labs.createIndex({ "field": 1 });
db.labs.createIndex({ "status": 1 });
db.labs.createIndex({ "createdAt": -1 });# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch
# Run specific test suite
npm test -- --grep "Authentication"# Health check
curl http://localhost:3001/api/health
# User registration
curl -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"username": "testuser",
"email": "test@example.com",
"password": "password123",
"interests": [1, 2, 3]
}'
# User login
curl -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "password123"}'
# Get recommendations (replace TOKEN)
curl -H "Authorization: Bearer TOKEN" \
"http://localhost:3001/api/recommendations?limit=5"
# Create event (replace TOKEN)
curl -X POST http://localhost:3001/api/events \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Test Event",
"description": "Test event description",
"date": "2024-06-15",
"location": "Test Location"
}'// TypeScript client example
class AtlasApiClient {
private baseURL: string;
private token: string | null = null;
constructor(baseURL: string = 'http://localhost:3001/api') {
this.baseURL = baseURL;
}
// Authentication methods
async login(username: string, password: string) {
const response = await fetch(`${this.baseURL}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const data = await response.json();
if (data.success) {
this.token = data.data.tokens.accessToken;
}
return data;
}
async register(userData: RegisterData) {
const response = await fetch(`${this.baseURL}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
return await response.json();
}
// Content methods
async getEvents(params?: { page?: number; limit?: number; search?: string }) {
const queryString = params ? '?' + new URLSearchParams(params as any) : '';
const response = await fetch(`${this.baseURL}/events${queryString}`);
return await response.json();
}
async getRecommendations(limit: number = 10) {
const response = await fetch(`${this.baseURL}/recommendations?limit=${limit}`, {
headers: { 'Authorization': `Bearer ${this.token}` }
});
return await response.json();
}
async createEvent(eventData: CreateEventData) {
const response = await fetch(`${this.baseURL}/events`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(eventData)
});
return await response.json();
}
}
// Usage
const client = new AtlasApiClient();
await client.login('username', 'password');
const recommendations = await client.getRecommendations(5);
const events = await client.getEvents({ page: 1, limit: 20 });-
Build the application:
npm run build
-
Set production environment variables:
export NODE_ENV=production export MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/atlas export JWT_SECRET=your-super-secure-256-bit-production-secret
-
Start the production server:
npm start
# Dockerfile
FROM node:18-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy source code
COPY . .
# Build application
RUN npm run build
# Expose port
EXPOSE 3001
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3001/api/health || exit 1
# Start application
CMD ["npm", "start"]# docker-compose.yml
version: '3.8'
services:
atlas-backend:
build: .
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongo:27017/atlas
- JWT_SECRET=your-production-secret
depends_on:
- mongo
restart: unless-stopped
mongo:
image: mongo:6.0
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
restart: unless-stopped
volumes:
mongo_data:# Example deployment to AWS Elastic Beanstalk
eb init atlas-backend --platform node.js
eb create production-environment
eb deploy- π JWT Authentication: Secure token-based authentication
- π‘οΈ Password Hashing: bcrypt with configurable rounds
- π« Rate Limiting: Prevent abuse with request rate limiting
- π Role-Based Access: Admin, moderator, and user roles
- π‘οΈ Input Validation: Comprehensive request validation
- π SQL Injection Protection: MongoDB parameterized queries
- π¨ Error Handling: Secure error responses without sensitive data
- Environment Variables: Never commit secrets to version control
- HTTPS Only: Use HTTPS in production (configure reverse proxy)
- CORS Configuration: Restrict CORS to trusted origins
- Regular Updates: Keep dependencies updated
- Security Headers: Use helmet.js for security headers
- Input Sanitization: Validate and sanitize all user inputs
- Audit Logging: Log security-relevant events
- β‘ Efficient Queries: Optimized MongoDB aggregation pipelines
- πΎ Caching: Response caching for frequently accessed data
- π Pagination: Built-in pagination for large datasets
- π Indexing: Strategic database indexing for query performance
- π Async Operations: Non-blocking asynchronous operations
// Health check endpoint
GET /api/health
{
"success": true,
"data": {
"status": "healthy",
"timestamp": "2024-01-15T10:30:00.000Z",
"uptime": "2d 5h 30m",
"version": "1.0.0",
"database": "connected",
"memory": {
"used": 45.2,
"total": 128.0,
"percentage": 35.3
}
}
}# Monitor application performance
npm install -g clinic
clinic doctor -- npm start
# Database performance monitoring
mongotop --host localhost:27017
mongostat --host localhost:27017We welcome contributions to Atlas! Please follow these guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes with proper TypeScript typing
- Add tests for new functionality
- Run the test suite:
npm test - Commit your changes:
git commit -m 'Add amazing feature' - Push to your branch:
git push origin feature/amazing-feature - Open a Pull Request
- TypeScript: All code must be properly typed
- ESLint: Follow the project's ESLint configuration
- Prettier: Use Prettier for code formatting
- Testing: Include tests for new features
- Documentation: Update documentation for API changes
feat: add user role management
fix: resolve JWT token expiration issue
docs: update API documentation
test: add tests for recommendations engine
refactor: optimize database queries
- README.md - Main project documentation (this file)
- ADMIN-DASHBOARD.md - Complete admin dashboard documentation
- API.md - Detailed API reference (auto-generated)
- DEPLOYMENT.md - Production deployment guide
- CONTRIBUTING.md - Contribution guidelines
- TypeScript Documentation: https://www.typescriptlang.org/docs/
- Express.js Guide: https://expressjs.com/en/guide/
- MongoDB Manual: https://docs.mongodb.com/manual/
- JWT.io: https://jwt.io/introduction/
Q: What is Atlas? A: Atlas is a comprehensive backend platform providing authentication, AI-powered recommendations, content management, and administrative features for modern web applications.
Q: What technologies does Atlas use? A: Atlas is built with TypeScript, Node.js, Express.js, MongoDB, and JWT for authentication. It includes AI-powered recommendations and a full admin dashboard.
Q: Is Atlas production-ready? A: Yes! Atlas includes comprehensive error handling, security features, performance optimizations, and production deployment guides.
Q: How do I set up admin access?
A: Create a user account, then update their role in MongoDB: db.users.updateOne({username: 'admin'}, {$set: {role: 'admin'}})
Q: How does the recommendation system work? A: The AI recommendation engine matches user interests with content, scoring items based on relevance, recency, and popularity.
Q: Can I customize the recommendation algorithm?
A: Yes! The recommendation engine in src/backend/modules/recommendations/engine.ts is fully customizable.
Q: How do I add new content types? A: Create a new MongoDB model, add CRUD routes, update the recommendations engine, and add admin management routes.
Q: How do I deploy Atlas to production?
A: See the deployment section above. Atlas supports Docker, cloud platforms (AWS, Azure, GCP), and traditional VPS deployments.
Q: What are the system requirements? A: Node.js v16+, MongoDB v4.4+, and at least 512MB RAM. Recommended: 2GB RAM and SSD storage for production.
Q: How do I scale Atlas? A: Atlas supports horizontal scaling with load balancers, MongoDB clustering, and Redis caching. See deployment documentation for details.
- π Advanced Search: Elasticsearch integration for enhanced search capabilities
- π§ Email System: Email notifications and verification system
- π± Mobile API: Optimized endpoints for mobile applications
- π Real-time Updates: WebSocket support for live data updates
- π Advanced Analytics: Machine learning-powered analytics and insights
- π Internationalization: Multi-language support
- π Third-party Integrations: OAuth providers, social media APIs
- π¦ Plugin System: Extensible plugin architecture
- v1.0.0 - Initial release with authentication, CRUD operations, and recommendations
- v1.1.0 - Added admin dashboard with comprehensive management features
- v1.2.0 - Enhanced analytics and reporting capabilities (coming soon)
- v2.0.0 - Real-time features and advanced search (planned)
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2024 Atlas Platform
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- Express.js Community - For the excellent web framework
- MongoDB Team - For the powerful NoSQL database
- TypeScript Team - For enhanced JavaScript development
- JWT.io - For secure authentication standards
- Open Source Community - For the countless libraries and tools that make this project possible
- π Documentation: Check the docs in this repository
- π Bug Reports: Open an issue on GitHub
- π‘ Feature Requests: Open a feature request issue
- π¬ Discussions: Join our GitHub Discussions
- π§ Email Support: support@atlas-platform.com
- GitHub: https://github.com/your-username/atlas
- Discord: Join our developer community
- Twitter: Follow @AtlasPlatform for updates
Built with β€οΈ for the developer community
β Star this repository if you find it helpful! β