REFACTOR: Belonging → Property system migration + utilities update

Property system:
- Rename belonging → property throughout (model, controller, routes, service)
- Add property sub-models: buildingModel, landModel, belongingModel
- Add property lifecycle events: createProperty, deleteProperty
- Add propertyStatus component (model, controller, routes, service, seeder)
- Add commodity and commodityTransaction model stubs

Infrastructure:
- Update transactionModel and transactionService
- Update events/index.js for new property events
- Update seeder (seederDBConnection, seederRunner)
- Update typesense client configuration
- Update upload utilities (bucket, minio)
- Update featureModel and featureSeeder
- Update categorySeeder
- Update TsApiFeatures utility
- Remove docker-compose.yml (moved to root)
- Remove legacy belonging component files
This commit is contained in:
2026-08-11 20:35:47 +03:30
parent a9432b96c0
commit ca911b97a0
35 changed files with 1504 additions and 1223 deletions
@@ -0,0 +1,48 @@
const catchAsync = require('../../globalErrorHandler/catchAsync')
const propertyStatusService = require('./propertyStatusService')
exports.getAllStatuses = catchAsync(async (req, res, next) => {
const statuses = await propertyStatusService.getAllStatuses()
res.status(200).json({
status: 'success',
results: statuses.length,
data: statuses,
})
})
exports.getStatus = catchAsync(async (req, res, next) => {
const status = await propertyStatusService.getStatus(req.params.statusId)
res.status(200).json({
status: 'success',
data: status,
})
})
exports.createStatus = catchAsync(async (req, res, next) => {
const status = await propertyStatusService.createStatus(req.body)
res.status(201).json({
status: 'success',
data: status,
})
})
exports.updateStatus = catchAsync(async (req, res, next) => {
const status = await propertyStatusService.updateStatus(req.params.statusId, req.body)
res.status(200).json({
status: 'success',
data: status,
})
})
exports.deleteStatus = catchAsync(async (req, res, next) => {
await propertyStatusService.deleteStatus(req.params.statusId)
res.status(204).json({
status: 'success',
data: null,
})
})
@@ -0,0 +1,28 @@
const mongoose = require('mongoose')
const propertyStatusSchema = new mongoose.Schema(
{
nativeName: {
type: String,
required: true,
},
englishName: {
type: String,
required: true,
unique: true,
},
// Color token for UI badge (success/info/warn/danger/secondary/contrast)
color: {
type: String,
default: 'secondary',
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
timestamps: true,
}
)
const PropertyStatus = mongoose.model('PropertyStatus', propertyStatusSchema)
module.exports = PropertyStatus
@@ -0,0 +1,20 @@
const express = require('express')
const propertyStatusController = require('./propertyStatusController')
const perm = require('../../middlewares/permissionMiddleware')
const loginCheck = require('../../middlewares/loginCheck')
const router = new express.Router()
router.use(loginCheck.loginProtect)
router.get('/admin/get-all', perm.requires('getallpropertystatuses', 'getallbelongingstatuses'), propertyStatusController.getAllStatuses)
router.get('/admin/get-one/:statusId', perm.requires('getapropertystatus', 'getabelongingstatus'), propertyStatusController.getStatus)
router.post('/admin/create', perm.requires('createapropertystatus', 'createabelongingstatus'), propertyStatusController.createStatus)
router.put('/admin/update/:statusId', perm.requires('updateapropertystatus', 'updateabelongingstatus'), propertyStatusController.updateStatus)
router.delete('/admin/delete/:statusId', perm.requires('deleteapropertystatus', 'deleteabelongingstatus'), propertyStatusController.deleteStatus)
module.exports = router
@@ -0,0 +1,32 @@
const PropertyStatus = require('./propertyStatusModel')
const chalk = require('chalk')
const runSeeder = async () => {
const statuses = [
// ── اصلی ────────────────────────────────────────────────────────────
{ nativeName: 'موجود', englishName: 'available', color: 'success' },
{ nativeName: 'فروخته شده', englishName: 'sold', color: 'contrast' },
{ nativeName: 'قولنامه', englishName: 'reserved', color: 'warn' },
{ nativeName: 'بلاک', englishName: 'blocked', color: 'danger' },
// ── تکمیلی ──────────────────────────────────────────────────────────
{ nativeName: 'در حال بررسی', englishName: 'in_review', color: 'info' },
{ nativeName: 'رهن', englishName: 'mortgaged', color: 'warn' },
{ nativeName: 'وراثتی', englishName: 'inherited', color: 'secondary' },
{ nativeName: 'مشاع', englishName: 'joint', color: 'secondary' },
{ nativeName: 'توقیف', englishName: 'seized', color: 'danger' },
{ nativeName: 'در دست ساخت', englishName: 'under_construction', color: 'info' },
]
await PropertyStatus.deleteMany({})
console.log(chalk.red('Deleted all property status records.'))
await PropertyStatus.create(statuses)
console.log(
chalk.green.bold(
`PROPERTY STATUS: Created ${statuses.length} status(es)`
)
)
}
module.exports = { runSeeder }
@@ -0,0 +1,42 @@
const PropertyStatus = require('./propertyStatusModel')
const AppError = require('../../globalErrorHandler/AppError')
const getAllStatuses = async () => {
return PropertyStatus.find({})
}
const getStatus = async (statusId) => {
const status = await PropertyStatus.findById(statusId)
if (!status) {
throw new AppError('NoPropertyStatusFound', 404, {})
}
return status
}
const createStatus = async (data) => {
return PropertyStatus.create(data)
}
const updateStatus = async (statusId, data) => {
const status = await PropertyStatus.findByIdAndUpdate(statusId, data, { new: true, runValidators: true })
if (!status) {
throw new AppError('NoPropertyStatusFound', 404, {})
}
return status
}
const deleteStatus = async (statusId) => {
const status = await PropertyStatus.findByIdAndDelete(statusId)
if (!status) {
throw new AppError('NoPropertyStatusFound', 404, {})
}
return null
}
module.exports = { getAllStatuses, getStatus, createStatus, updateStatus, deleteStatus }