Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/controllers/sellerController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const Project = require('../models/Project');
const Transaction = require('../models/Transaction');
const User = require('../models/User');


exports.getSellerProjects = async (req, res, next) => {
try {
const sellerId = req.user.id;
const projects = await Project.find({ seller: sellerId });
res.status(200).json({ success: true, count: projects.length, data: projects });
} catch (err) {
next(err);
}
};


exports.getSellerSoldProjects = async (req, res, next) => {
try {
const sellerId = req.user.id;

const soldProjects = await Transaction.find({ seller: sellerId, type: 'project_sale' }).populate('project');
Copy link

Copilot AI Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The API returns Transaction objects for sold projects, but users might expect Project objects with sale information. Consider restructuring to return projects with their sale transaction details instead.

Suggested change
const soldProjects = await Transaction.find({ seller: sellerId, type: 'project_sale' }).populate('project');
const soldTransactions = await Transaction.find({ seller: sellerId, type: 'project_sale' }).populate('project');
const soldProjects = soldTransactions
.filter(tx => tx.project) // Ensure project is populated
.map(tx => {
const projectObj = tx.project.toObject ? tx.project.toObject() : { ...tx.project };
projectObj.saleInfo = {
transactionId: tx._id,
soldAt: tx.createdAt,
price: tx.amount,
buyer: tx.buyer,
// add other relevant transaction fields as needed
};
return projectObj;
});

Copilot uses AI. Check for mistakes.
res.status(200).json({ success: true, count: soldProjects.length, data: soldProjects });
} catch (err) {
next(err);
}
};


exports.getSellerActivity = async (req, res, next) => {
try {
const sellerId = req.user.id;

const [projects, soldProjects, transactions] = await Promise.all([
Project.find({ seller: sellerId }),
Transaction.find({ seller: sellerId, type: 'project_sale' }).populate('project'),
Transaction.find({ seller: sellerId })
]);
Copy link

Copilot AI Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getSellerActivity function performs redundant queries. The soldProjects query is a subset of the transactions query (transactions with type: 'project_sale'), so you could filter the transactions result instead of making a separate database call.

Suggested change
]);
const [projects, transactions] = await Promise.all([
Project.find({ seller: sellerId }),
Transaction.find({ seller: sellerId }).populate('project')
]);
const soldProjects = transactions.filter(tx => tx.type === 'project_sale');

Copilot uses AI. Check for mistakes.
res.status(200).json({
success: true,
data: {
createdProjects: projects,
soldProjects: soldProjects,
transactions: transactions
}
});
} catch (err) {
next(err);
}
};
33 changes: 33 additions & 0 deletions src/models/Project.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const mongoose = require('mongoose');

const ProjectSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: String,
seller: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
status: {
type: String,
enum: ['active', 'sold', 'inactive'],
default: 'active',
},
price: {
type: Number,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
Copy link

Copilot AI Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timestamps option is redundant since you already have explicit createdAt field. Either remove the explicit createdAt field and rely on timestamps: true, or remove the timestamps option to avoid confusion.

Suggested change
},

Copilot uses AI. Check for mistakes.
soldAt: Date,
metadata: mongoose.Schema.Types.Mixed,
}, {
timestamps: true,
});

module.exports = mongoose.model('Project', ProjectSchema);
12 changes: 11 additions & 1 deletion src/models/Transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,19 @@ const TransactionSchema = new mongoose.Schema({
},
type: {
type: String,
enum: ['transfer', 'contract_interaction', 'token_transfer', 'nft_transfer'],
enum: ['transfer', 'contract_interaction', 'token_transfer', 'nft_transfer', 'project_sale'],
default: 'transfer',
},

// Add seller and project fields for project sale tracking
seller: {
type: mongoose.Schema.ObjectId,
ref: 'User',
},
project: {
type: mongoose.Schema.ObjectId,
ref: 'Project',
},
tokenAddress: {
type: String,
lowercase: true,
Expand Down
3 changes: 3 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const userRoutes = require('./users');
const walletRoutes = require('./wallets');
const transactionRoutes = require('./transactions');
const web3Routes = require('./web3');
const sellerRoutes = require('./seller');

// API version and info
router.get('/', (req, res) => {
Expand All @@ -20,6 +21,7 @@ router.get('/', (req, res) => {
wallets: '/api/wallets',
transactions: '/api/transactions',
web3: '/api/web3',
seller: '/api/seller',
},
documentation: '/api/docs',
});
Expand All @@ -31,5 +33,6 @@ router.use('/users', userRoutes);
router.use('/wallets', walletRoutes);
router.use('/transactions', transactionRoutes);
router.use('/web3', web3Routes);
router.use('/seller', sellerRoutes);

module.exports = router;
21 changes: 21 additions & 0 deletions src/routes/seller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const express = require('express');
const router = express.Router();
const { protect, authorize } = require('../middleware/auth');
const {
getSellerProjects,
getSellerSoldProjects,
getSellerActivity
} = require('../controllers/sellerController');


router.use(protect);
router.use(authorize('user'));


router.get('/projects', getSellerProjects);

router.get('/sold-projects', getSellerSoldProjects);

router.get('/activity', getSellerActivity);

module.exports = router;