feat: Introduce app feature flags

This commit refactors the application settings to include a new `AppFeatures` interface. This allows for granular control over which features are enabled for the application.

The `AppFeatures` object includes boolean flags for:
- `multiCondo`: Enables or disables the multi-condominium management feature.
- `tickets`: Placeholder for future ticket system integration.
- `payPal`: Enables or disables PayPal payment gateway integration.
- `notices`: Enables or disables the display and management of notices.

These flags are now fetched and stored in the application state, influencing UI elements and logic across various pages to conditionally render features based on their enabled status. For example, the multi-condo selection in `Layout.tsx` and the notice display in `FamilyList.tsx` are now gated by these feature flags. The `FamilyDetail.tsx` page also uses the `payPal` flag to conditionally enable the PayPal payment option.

The `SettingsPage.tsx` has been updated to include a new 'features' tab for managing these flags.
This commit is contained in:
2025-12-07 20:21:01 +01:00
parent 5311400615
commit 919be985c9
8 changed files with 243 additions and 67 deletions

View File

@@ -67,10 +67,28 @@ const initDb = async () => {
CREATE TABLE IF NOT EXISTS settings (
id INT PRIMARY KEY,
current_year INT,
smtp_config JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'}
smtp_config JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'},
features JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'}
)
`);
// Migration: Add features column if not exists
try {
let hasFeatures = false;
if (DB_CLIENT === 'postgres') {
const [cols] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='settings'");
hasFeatures = cols.some(c => c.column_name === 'features');
} else {
const [cols] = await connection.query("SHOW COLUMNS FROM settings");
hasFeatures = cols.some(c => c.Field === 'features');
}
if (!hasFeatures) {
console.log('Migrating: Adding features to settings...');
await connection.query("ALTER TABLE settings ADD COLUMN features JSON");
}
} catch(e) { console.warn("Settings migration warning:", e.message); }
// 1. Condos Table
await connection.query(`
CREATE TABLE IF NOT EXISTS condos (
@@ -300,12 +318,25 @@ const initDb = async () => {
// --- SEEDING ---
const [rows] = await connection.query('SELECT * FROM settings WHERE id = 1');
const defaultFeatures = {
multiCondo: true,
tickets: true,
payPal: true,
notices: true
};
if (rows.length === 0) {
const currentYear = new Date().getFullYear();
await connection.query(
'INSERT INTO settings (id, current_year) VALUES (1, ?)',
[currentYear]
'INSERT INTO settings (id, current_year, features) VALUES (1, ?, ?)',
[currentYear, JSON.stringify(defaultFeatures)]
);
} else {
// Ensure features column has defaults if null
if (!rows[0].features) {
await connection.query('UPDATE settings SET features = ? WHERE id = 1', [JSON.stringify(defaultFeatures)]);
console.log("Seeded default features settings.");
}
}
// ENSURE ADMIN EXISTS AND HAS CORRECT ROLE
@@ -332,4 +363,4 @@ const initDb = async () => {
}
};
module.exports = { pool: dbInterface, initDb };
module.exports = { pool: dbInterface, initDb };