forked from rohit/spurrin-backend
doc views by user
This commit is contained in:
parent
ba185c0cf5
commit
7531702923
24
.env.example
24
.env.example
@ -1,15 +1,15 @@
|
||||
|
||||
|
||||
DB_HOST=localhost
|
||||
DB_USER=root
|
||||
DB_USER=testuser
|
||||
DB_PASSWORD=Admin@123
|
||||
DB_NAME=spurrindev
|
||||
DB_NAME=spurrinai
|
||||
|
||||
EMAIL_USER=spurrinai@gmail.com
|
||||
EMAIL_PASS=wblspqqpzpxfcjaq
|
||||
EMAIL_USER=info@spurrin.com
|
||||
EMAIL_PASS=app_password
|
||||
EMAIL_HOST=smtp.gmail.com
|
||||
EMAIL_PORT=587
|
||||
|
||||
|
||||
|
||||
JWT_ACCESS_TOKEN_SECRET=jN4!pY9*d#T2@x$L7wq&Z8^gFc%X5@K#m
|
||||
JWT_REFRESH_TOKEN_SECRET=Lx$Z7#T2^d&n9!Y4%K8@Fcg*m#qX5p@wL
|
||||
JWT_ACCESS_TOKEN_EXPIRY=5h
|
||||
@ -19,12 +19,8 @@ JWT_REFRESH_TOKEN_EXPIRY=7d
|
||||
BACK_URL = http://localhost:3000/
|
||||
|
||||
# email
|
||||
|
||||
mail = srikanth.mallikarjuna@tech4biz.io
|
||||
apppassword = 0peCQnLEZVfZ
|
||||
|
||||
# mail = info@spurrin.com
|
||||
# apppassword=nbF314CF84Ja
|
||||
mail = info@spurrin.com
|
||||
apppassword= app_password
|
||||
|
||||
# PORT
|
||||
PORT = 3000
|
||||
@ -38,6 +34,4 @@ SENDER_SECURITY = false
|
||||
|
||||
# SENDER_PORT = 465
|
||||
# SENDER_SECURITY = true
|
||||
|
||||
SSL_CERT = "/home/ubuntu/spurrinai-backend-node/fullchain.pem"
|
||||
SSL_KEY = "/home/ubuntu/spurrinai-backend-node/privkey.pem"
|
||||
OPENAI_API_KEY= your_api_key
|
||||
|
||||
7
checklist.txt
Normal file
7
checklist.txt
Normal file
@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS document_views (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
document_id INT NOT NULL,
|
||||
user_id INT NOT NULL,
|
||||
user_role ENUM('Superadmin', 'Admin', 'Viewer', 'Spurrinadmin', 'AppUser') NOT NULL,
|
||||
viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
67
readme.md
67
readme.md
@ -6,10 +6,10 @@ A Node.js backend application for SpurrinAI platform.
|
||||
|
||||
```
|
||||
project-root/
|
||||
├── src/ # Source code
|
||||
├── src/
|
||||
│ ├── app.js # App entry point
|
||||
│ ├── config/ # Configuration files
|
||||
│ ├── controllers/ # Route controllers
|
||||
│ ├── controllers/ # Route controllers with business logic
|
||||
│ ├── middleware/ # Custom middleware
|
||||
│ ├── migrations/ # Database migrations
|
||||
│ ├── routes/ # Route definitions
|
||||
@ -32,8 +32,8 @@ project-root/
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone -b dev https://git.tech4biz.wiki/Tech4Biz-Services/spurrin-cleaned-node.git
|
||||
cd spurrinai-backend
|
||||
git clone git_repository_url
|
||||
cd spurrinai-backend (or respected folder )
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
@ -58,31 +58,10 @@ npm run setup
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
2. Run tests:
|
||||
# Run migrations up
|
||||
```bash
|
||||
# Run all tests
|
||||
npm test
|
||||
|
||||
# Run unit tests only
|
||||
npm run test:unit
|
||||
|
||||
# Run integration tests only
|
||||
npm run test:integration
|
||||
npm run migrate:up
|
||||
```
|
||||
|
||||
3. Code Quality:
|
||||
```bash
|
||||
# Lint code
|
||||
npm run lint
|
||||
|
||||
# Fix linting issues
|
||||
npm run lint:fix
|
||||
|
||||
# Format code
|
||||
npm run format
|
||||
```
|
||||
|
||||
## Production Mode
|
||||
|
||||
1. Build the application:
|
||||
@ -154,40 +133,6 @@ npm run migrate:up
|
||||
npm run migrate:down
|
||||
```
|
||||
|
||||
## API Documentation
|
||||
|
||||
Detailed API documentation can be found in the [docs/API.md](docs/API.md) file.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Required environment variables in `.env`:
|
||||
|
||||
```env
|
||||
# Server Configuration
|
||||
PORT=3000
|
||||
NODE_ENV=development
|
||||
|
||||
# Database Configuration
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=spurrinai
|
||||
DB_USER=postgres
|
||||
DB_PASSWORD=your_password
|
||||
|
||||
# JWT Configuration
|
||||
JWT_SECRET=your_jwt_secret
|
||||
JWT_EXPIRES_IN=24h
|
||||
|
||||
# Email Configuration
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your_email@gmail.com
|
||||
SMTP_PASS=your_app_password
|
||||
|
||||
# File Upload Configuration
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=5242880 # 5MB
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ async function startServer() {
|
||||
|
||||
// Root endpoint
|
||||
app.get('/', (req, res) => {
|
||||
res.send("SpurrinAI Backend is running!");
|
||||
res.send("SpurrinAI Backend is running!!!");
|
||||
});
|
||||
|
||||
app.get('/logs', (req, res) => {
|
||||
|
||||
@ -174,25 +174,6 @@ exports.getActiveHospitalsAnalysis = async (req, res) => {
|
||||
`;
|
||||
|
||||
|
||||
// const query = `
|
||||
// SELECT
|
||||
// h.id,
|
||||
// h.name_hospital as hospital_name,
|
||||
// h.hospital_code,
|
||||
// h.status,
|
||||
// h.onboarding_status,
|
||||
// COUNT(DISTINCT au.id) as total_app_users,
|
||||
// COUNT(DISTINCT il.id) as total_interactions,
|
||||
// MAX(il.created_at) as last_interaction_date
|
||||
// FROM hospitals h
|
||||
// LEFT JOIN app_users au ON h.hospital_code = au.hospital_code
|
||||
// LEFT JOIN interaction_logs il ON h.hospital_code = il.hospital_code
|
||||
// ${start_date && end_date ? 'WHERE il.created_at BETWEEN ? AND ?' : ''}
|
||||
// GROUP BY h.id
|
||||
// HAVING total_interactions > 0
|
||||
// ORDER BY total_interactions DESC
|
||||
// `;
|
||||
|
||||
const params = start_date && end_date ? [start_date, end_date] : [];
|
||||
const hospitals = await db.query(query, params);
|
||||
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
const bcrypt = require("bcrypt");
|
||||
const db = require("../config/database"); // Database connection
|
||||
const fs = require("fs");
|
||||
const JWT_ACCESS_TOKEN_SECRET = process.env.JWT_ACCESS_TOKEN_SECRET;
|
||||
const JWT_ACCESS_TOKEN_EXPIRY = "5h";
|
||||
const jwt = require("jsonwebtoken");
|
||||
const nlp = require("compromise");
|
||||
const nodemailer = require("nodemailer");
|
||||
const sender_mail = process.env.mail;
|
||||
const sender_app_password = process.env.apppassword;
|
||||
const sender_port = process.env.SENDER_PORT;
|
||||
const sender_security = process.env.SENDER_SECURITY;
|
||||
const path = require('path')
|
||||
@ -24,11 +20,7 @@ const transporter = nodemailer.createTransport({
|
||||
auth: {
|
||||
user: "kavya.j@tech4biz.io", // Your Zoho email address
|
||||
pass: "8pQfkBw8gbrz", // Your Zoho App Password (not your account password)
|
||||
},
|
||||
// tls: {
|
||||
// rejectUnauthorized: false, // Allow self-signed certificates
|
||||
// minVersion: "TLSv1.2"
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
exports.initWebSocket = (io) => {
|
||||
@ -110,12 +102,6 @@ exports.updateSettings = async (req, res) => {
|
||||
const userId = req.user.id; // Assuming user is authenticated and userId is available
|
||||
const { pin, pin_enabled, remember_me } = req.body;
|
||||
|
||||
console.log("data---",pin,pin_enabled,remember_me)
|
||||
|
||||
// if (typeof pin_enabled !== 'boolean' || typeof remember_me !== 'boolean') {
|
||||
// return res.status(400).json({ error: 'Invalid data format' });
|
||||
// }
|
||||
|
||||
// Validate pin (if provided)
|
||||
if (pin && (typeof pin !== 'string' || pin.length !== 4)) {
|
||||
return res.status(400).json({ error: 'Invalid PIN format. Must be a 4-digit string.' });
|
||||
@ -211,14 +197,6 @@ exports.signup = async (req, res) => {
|
||||
try {
|
||||
const { pin, pin_status,remember_me, email, password, hospital_code, username } = req.body;
|
||||
|
||||
console.log("pin--",pin)
|
||||
console.log("pin_status",pin_status)
|
||||
console.log("email--",email)
|
||||
console.log('password---',password)
|
||||
console.log("hospital_code---",hospital_code)
|
||||
console.log("username--",username)
|
||||
console.log("remember_me--",remember_me)
|
||||
|
||||
if (!email || !password || !hospital_code || !username) {
|
||||
return res.status(400).json({
|
||||
error: "Email, password, username, and hospital code are required",
|
||||
@ -228,8 +206,6 @@ exports.signup = async (req, res) => {
|
||||
const pin_enabled = (pin_status === undefined || pin_status === '') ? 0 : pin_status;
|
||||
const remember_me_ = (remember_me === undefined || remember_me === '') ? 0 : remember_me;
|
||||
|
||||
|
||||
|
||||
// Check if the hospital_code exists in the `hospitals` table
|
||||
const hospitalQuery =
|
||||
"SELECT hospital_code FROM hospitals WHERE hospital_code = ?";
|
||||
@ -681,8 +657,6 @@ exports.deleteAppUser = async (req, res) => {
|
||||
const { id } = req.params;
|
||||
const { hospital_code } = req.user;
|
||||
|
||||
console.log('req.user------------------------------------------------------------------',req.user)
|
||||
|
||||
// Check if the user exists
|
||||
const appUserquery = "SELECT * FROM app_users WHERE id = ?";
|
||||
const users = await db.query(appUserquery, [id]);
|
||||
|
||||
@ -498,3 +498,62 @@ exports.updateDocumentViews = async (req, res) => {
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// POST /documents/:id/view
|
||||
exports.logDocumentView = async (req, res) => {
|
||||
const documentId = parseInt(req.params.id);
|
||||
const userId = req.user.id; // from decoded JWT or session
|
||||
const userRole = req.user.role; // e.g., 'Admin', 'Viewer', etc.
|
||||
|
||||
if (!documentId || !userId || !userRole) {
|
||||
return res.status(400).json({ error: 'Missing required information' });
|
||||
}
|
||||
|
||||
try {
|
||||
const insertQuery = `
|
||||
INSERT INTO document_views (document_id, user_id, user_role)
|
||||
VALUES (?, ?, ?)
|
||||
`;
|
||||
|
||||
const result = await db.query(insertQuery, [documentId, userId, userRole]);
|
||||
|
||||
res.status(200).json({ message: 'View logged successfully', insertId: result.insertId });
|
||||
} catch (error) {
|
||||
console.error('Error logging document view:', error.message);
|
||||
res.status(500).json({ message: 'Error logging view' });
|
||||
}
|
||||
};
|
||||
|
||||
// GET /documents/:id/views
|
||||
exports.getDocumentViewCount = async (req, res) => {
|
||||
const documentId = parseInt(req.params.id);
|
||||
|
||||
if (!documentId) {
|
||||
return res.status(400).json({ error: 'Document ID is required' });
|
||||
}
|
||||
|
||||
try {
|
||||
const query = `
|
||||
SELECT
|
||||
document_id,
|
||||
user_id AS viewed_by,
|
||||
user_role,
|
||||
viewed_at
|
||||
FROM document_views
|
||||
WHERE document_id = ?
|
||||
ORDER BY viewed_at DESC
|
||||
`;
|
||||
|
||||
const [views] = await db.query(query, [documentId]);
|
||||
|
||||
res.status(200).json({
|
||||
documentId,
|
||||
totalViews: views.length,
|
||||
views,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching view details:', error.message);
|
||||
res.status(500).json({ message: 'Error fetching view details' });
|
||||
}
|
||||
};
|
||||
|
||||
@ -76,5 +76,8 @@ router.delete(
|
||||
documentController.deleteDocument
|
||||
);
|
||||
|
||||
router.post('/:id/view', authMiddleware.authenticateToken, documentController.logDocumentView);
|
||||
router.get('/:id/views',authMiddleware.authenticateToken, documentController.getDocumentViewCount);
|
||||
|
||||
|
||||
module.exports = router;
|
||||
Loading…
Reference in New Issue
Block a user