{"id":16359,"library":"ffc-database","title":"FFC Database Module","description":"ffc-database is an npm module developed by DEFRA, providing a structured utility layer for database interactions within FFC services. It is built upon the Sequelize ORM, abstracting common setup and model loading patterns. The module simplifies connecting to SQL databases (e.g., PostgreSQL, as shown in examples) by taking a configuration object, dynamically loading Sequelize models from a specified filesystem path, and exposing the connected Sequelize instance and loaded models. The current stable version is 1.0.24. While specific release cadence is not provided, its versioning and association with government services suggest a focus on stability and compatibility within its ecosystem. Its key differentiator lies in its opinionated, service-centric wrapper around Sequelize, streamlining database access for specific internal FFC applications.","status":"active","version":"1.0.24","language":"javascript","source_language":"en","source_url":"https://github.com/DEFRA/ffc-database","tags":["javascript"],"install":[{"cmd":"npm install ffc-database","lang":"bash","label":"npm"},{"cmd":"yarn add ffc-database","lang":"bash","label":"yarn"},{"cmd":"pnpm add ffc-database","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the underlying ORM functionality for database interactions, model definition, and querying.","package":"sequelize","optional":false},{"reason":"Required for connecting to a PostgreSQL database, as indicated by the example `dialect: 'postgres'` configuration. Other database drivers (e.g., `mysql2`) would be needed for different dialects.","package":"pg","optional":true}],"imports":[{"note":"The package primarily uses CommonJS `require()`. Direct ES module `import` syntax may not work without additional configuration or transpilation due to its CommonJS export structure.","wrong":"import Base from 'ffc-database'","symbol":"Base","correct":"const Base = require('ffc-database')"},{"note":"The `sequelize` instance is exposed directly on the object returned by `connect()`, allowing access to all native Sequelize methods like `authenticate()`, `close()`, and `query()`.","symbol":"db.sequelize","correct":"const dbBase = new Base(config);\nconst db = dbBase.connect();\n// Access sequelize instance:\ndb.sequelize.authenticate();"},{"note":"Models are automatically loaded from `modelPath` and attached to the `db` object with their defined names (e.g., `Payment`). This pattern is part of the `ffc-database` abstraction.","symbol":"db.ModelName","correct":"const dbBase = new Base(config);\nconst db = dbBase.connect();\n// Access models by their defined name (e.g., 'Payment'):\nawait db.Payment.findAll();"}],"quickstart":{"code":"const Base = require('ffc-database');\n\nconst config = {\n  dialect: 'postgres',\n  host: process.env.DB_HOST ?? 'localhost',\n  port: parseInt(process.env.DB_PORT ?? '5432', 10),\n  database: process.env.DB_NAME ?? 'ffc_pay',\n  username: process.env.DB_USER ?? 'ffc_user',\n  password: process.env.DB_PASSWORD ?? 'ffc_password',\n  modelPath: './models', // Assuming models directory exists in CWD\n  ssl: process.env.DB_SSL === 'true' ?? false,\n  logging: process.env.NODE_ENV !== 'production'\n};\n\n// Minimal model file example (./models/payment.js):\n// module.exports = (sequelize, DataTypes) => {\n//   const Payment = sequelize.define('Payment', {\n//     amount: { type: DataTypes.DECIMAL },\n//     status: { type: DataTypes.STRING }\n//   });\n//   Payment.associate = (models) => {}; // Define associations here\n//   return Payment;\n// };\n\nasync function runDbOperations() {\n  let dbBase;\n  let db;\n  try {\n    dbBase = new Base(config);\n    db = await dbBase.connect();\n    console.log('Database connected successfully.');\n\n    // Example: Run a raw query\n    const [results, metadata] = await db.sequelize.query(\n      'SELECT 1 + 1 as solution;',\n      { type: db.sequelize.QueryTypes.SELECT }\n    );\n    console.log('Query result:', results);\n\n    // Assuming a 'Payment' model exists and is defined in './models/payment.js'\n    // const payments = await db.Payment.findAll();\n    // console.log('Found payments:', payments);\n\n  } catch (error) {\n    console.error('Database operation failed:', error);\n  } finally {\n    if (db && db.sequelize) {\n      await db.sequelize.close();\n      console.log('Database connection closed.');\n    }\n  }\n}\n\nrunDbOperations();","lang":"javascript","description":"This quickstart demonstrates how to instantiate the `ffc-database` module, connect to a PostgreSQL database using environment variables for sensitive data, dynamically load Sequelize models, execute a simple raw SQL query, and gracefully close the database connection."},"warnings":[{"fix":"For ESM projects, consider using dynamic `import()` or ensuring your project's `package.json` correctly handles module types. For Sequelize specifically, ensure compatibility by checking how it's imported in ESM contexts.","message":"The module's examples and internal structure primarily use CommonJS (`require`). Integrating into a pure ES module (ESM) Node.js project may require specific `package.json` configurations (`'type': 'commonjs'`) or transpilation to avoid `SyntaxError: Named export 'X' not found` or `require() of ES modules is not supported` errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Verify that `config.modelPath` is an absolute or correct relative path to your model directory. Ensure each model file exports a function that accepts `sequelize` and `DataTypes` as arguments and returns the defined model.","message":"The `modelPath` configuration expects a filesystem path to a directory containing JavaScript files that define Sequelize models. These files must adhere to the `module.exports = (sequelize, DataTypes) => { ... }` pattern. Incorrect paths or malformed model files will prevent models from being loaded.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement connection closing in application shutdown hooks (e.g., `process.on('SIGTERM', ...)`) or after a block of operations where the connection is no longer needed. Ensure a new `Base` instance is created if `connect()` is to be called again.","message":"The `sequelize.close()` method should be called when your application is shutting down to release database connections. Once called, the `sequelize` instance cannot re-establish connections, requiring a new instance if further database operations are needed.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Verify the database server is running and accessible. Double-check `host`, `port`, `username`, `password`, and `database` in your `config` object. Ensure no firewall rules are blocking the connection.","cause":"The database server is not running, is inaccessible from the host, or the connection parameters (host, port, username, password) are incorrect.","error":"SequelizeConnectionError: connect ECONNREFUSED"},{"fix":"Install the required database dialect package: `npm install --save pg` for PostgreSQL, `npm install --save mysql2` for MySQL, etc.","cause":"The necessary database driver (e.g., `pg` for PostgreSQL) is not installed as a dependency in your project.","error":"Error: Cannot find module 'pg'"},{"fix":"Confirm that `config.modelPath` points to the correct directory. Check the model file (`yourmodelname.js`) for syntax errors, ensure it exports a function, and that `sequelize.define` is correctly used within it.","cause":"The model `YourModelName` was not correctly loaded or defined, possibly due to an incorrect `modelPath` or an error in the model's file structure.","error":"TypeError: db.YourModelName.findAll is not a function"}],"ecosystem":"npm"}