235 lines
6.9 KiB
JavaScript
235 lines
6.9 KiB
JavaScript
const BaseRepository = require('../../../src/database/repository');
|
|
const logger = require('../../../src/utils/logger');
|
|
|
|
/**
|
|
* Base Financial Repository
|
|
*
|
|
* Extends core BaseRepository to handle pg_ prefixed plugin tables.
|
|
* All financial plugin repositories should extend this class.
|
|
*
|
|
* Features:
|
|
* - Uses pg_ prefix to identify plugin tables in main schema
|
|
* - Inherits all BaseRepository methods (findOne, findAll, create, etc.)
|
|
* - Multi-tenant support via site_id
|
|
* - Database abstraction (works with any supported database)
|
|
*/
|
|
class BaseFinancialRepository extends BaseRepository {
|
|
constructor(tableName) {
|
|
super(tableName);
|
|
this.schema = 'public'; // Use main schema with pg_ prefixed tables
|
|
}
|
|
|
|
/**
|
|
* Get database connection
|
|
* @returns {Object} Database connection
|
|
*/
|
|
getConnection() {
|
|
if (global.dbConnection && typeof global.dbConnection.getConnection === 'function') {
|
|
return global.dbConnection.getConnection();
|
|
}
|
|
throw new Error('No database connection available');
|
|
}
|
|
|
|
/**
|
|
* Check if connection is Supabase client
|
|
* @param {Object} connection
|
|
* @returns {boolean}
|
|
*/
|
|
isSupabase(connection) {
|
|
return connection && typeof connection.from === 'function' && typeof connection.auth === 'object';
|
|
}
|
|
|
|
/**
|
|
* Override findAll to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async findAll(criteria = {}, options = {}) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
// Supabase style - use pg_ prefixed tables in public schema
|
|
let query = connection.from(this.tableName).select('*');
|
|
|
|
// Apply criteria
|
|
if (Object.keys(criteria).length > 0) {
|
|
query = query.match(criteria);
|
|
}
|
|
|
|
// Apply ordering
|
|
if (options.orderBy) {
|
|
const ascending = options.orderDirection === 'asc' || options.orderDirection === 'ASC';
|
|
query = query.order(options.orderBy, { ascending });
|
|
}
|
|
|
|
// Apply limit
|
|
if (options.limit) query = query.limit(options.limit);
|
|
|
|
const { data, error } = await query;
|
|
if (error) throw error;
|
|
return data || [];
|
|
} else {
|
|
// Knex style - for other databases
|
|
return super.findAll(criteria, options);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override findOne to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async findOne(criteria) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const { data, error } = await connection
|
|
.from(this.tableName)
|
|
.select('*')
|
|
.match(criteria)
|
|
.limit(1);
|
|
if (error) throw error;
|
|
return data && data[0];
|
|
} else {
|
|
return super.findOne(criteria);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override create to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async create(data) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const { data: result, error } = await connection
|
|
.from(this.tableName)
|
|
.insert([data])
|
|
.select();
|
|
if (error) throw error;
|
|
return result && result[0];
|
|
} else {
|
|
return super.create(data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override updateById to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async updateById(id, updateData) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const { data, error } = await connection
|
|
.from(this.tableName)
|
|
.update(updateData)
|
|
.eq('id', id)
|
|
.select();
|
|
if (error) throw error;
|
|
return data && data[0];
|
|
} else {
|
|
return super.updateById(id, updateData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override deleteById to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async deleteById(id) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const { error } = await connection
|
|
.from(this.tableName)
|
|
.delete()
|
|
.eq('id', id);
|
|
if (error) throw error;
|
|
return true;
|
|
} else {
|
|
return super.deleteById(id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override count to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async count(criteria = {}) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const { count, error } = await connection
|
|
.from(this.tableName)
|
|
.select('*', { count: 'exact', head: true })
|
|
.match(criteria);
|
|
if (error) throw error;
|
|
return count || 0;
|
|
} else {
|
|
return super.count(criteria);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override findWhere to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async findWhere(conditions, options = {}) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
let query = connection.from(this.tableName).select('*');
|
|
|
|
// Apply conditions
|
|
for (const [field, condition] of Object.entries(conditions)) {
|
|
if (condition.eq !== undefined) query = query.eq(field, condition.eq);
|
|
if (condition.neq !== undefined) query = query.neq(field, condition.neq);
|
|
if (condition.gt !== undefined) query = query.gt(field, condition.gt);
|
|
if (condition.gte !== undefined) query = query.gte(field, condition.gte);
|
|
if (condition.lt !== undefined) query = query.lt(field, condition.lt);
|
|
if (condition.lte !== undefined) query = query.lte(field, condition.lte);
|
|
if (condition.like !== undefined) query = query.like(field, condition.like);
|
|
if (condition.in !== undefined) query = query.in(field, condition.in);
|
|
}
|
|
|
|
// Apply ordering
|
|
if (options.orderBy) {
|
|
const ascending = options.orderDirection === 'asc' || options.orderDirection === 'ASC';
|
|
query = query.order(options.orderBy, { ascending });
|
|
}
|
|
|
|
// Apply limit
|
|
if (options.limit) query = query.limit(options.limit);
|
|
|
|
const { data, error } = await query;
|
|
if (error) throw error;
|
|
return data || [];
|
|
} else {
|
|
return super.findWhere(conditions, options);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override paginate to handle pg_ prefixed tables in main schema
|
|
*/
|
|
async paginate(criteria = {}, page = 1, limit = 10, options = {}) {
|
|
const connection = this.getConnection();
|
|
if (this.isSupabase(connection)) {
|
|
const offset = (page - 1) * limit;
|
|
let query = connection
|
|
.from(this.tableName)
|
|
.select('*', { count: 'exact' })
|
|
.match(criteria);
|
|
query = query.range(offset, offset + limit - 1);
|
|
|
|
const { data, error, count } = await query;
|
|
if (error) throw error;
|
|
const total = typeof count === 'number' ? count : (data ? data.length : 0);
|
|
const totalPages = Math.ceil(total / limit);
|
|
|
|
return {
|
|
data: data || [],
|
|
pagination: {
|
|
page,
|
|
limit,
|
|
total,
|
|
totalPages,
|
|
hasNext: page < totalPages,
|
|
hasPrev: page > 1
|
|
}
|
|
};
|
|
} else {
|
|
return super.paginate(criteria, page, limit, options);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = BaseFinancialRepository;
|
|
|
|
|