### Instruction:
Develop a Node.js application that uses Express.js and interacts with a PostgreSQL database to manage a basic blog system. The application should support creating, reading, updating, and deleting blog posts, as well as adding comments to existing posts.
PLAINFORMAT

### Response:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = process.env.PORT || 3000;
const pgp = require('pg-promise')();
require('dotenv').config();
const db = pgp(process.env.DATABASE_URL);
const router = express.Router();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// Routes
app.use('/api', router);

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

// Get all posts
router.get('/posts', async (req, res) => {
  try {
    const posts = await db.any('SELECT * FROM posts ORDER BY created_at DESC');
    res.json(posts);
  } catch (error) {
    res.status(500).json({ error: 'An error occurred while fetching posts' });
  }
});

// Get a single post by ID
router.get('/posts/:id', async (req, res) => {
  try {
    const postId = parseInt(req.params.id);
    const post = await db.one('SELECT * FROM posts WHERE id = $1', [postId]);
    res.json(post);
  } catch (error) {
    res.status(404).json({ error: 'Post not found' });
  }
});

// Create a new post
router.post('/posts', async (req, res) => {
  try {
    const { title, content } = req.body;
    const result = await db.one(
      'INSERT INTO posts(title, content) VALUES($1, $2) RETURNING *',
      [title, content]
    );
    res.status(201).json(result);
  } catch (error) {
    res.status(400).json({ error: 'An error occurred while creating the post' });
  }
});

// Update an existing post
router.put('/posts/:id', async (req, res) => {
  try {
    const postId = parseInt(req.params.id);
    const { title, content } = req.body;
    const result = await db.one(
      'UPDATE posts SET title = $1, content = $2 WHERE id = $3 RETURNING *',
      [title, content, postId]
    );
    res.json(result);
  } catch (error) {
    res.status(400).json({ error: 'An error occurred while updating the post' });
  }
});

// Delete a post
router.delete('/posts/:id', async (req, res) => {
  try {
    const postId = parseInt(req.params.id);
    await db.none('DELETE FROM posts WHERE id = $1', [postId]);
    res.status(204).send();
  } catch (error) {
    res.status(400).json({ error: 'An error occurred while deleting the post' });
  }
});

// Get comments for a post
router.get('/posts/:id/comments', async (req, res) => {
  try {
    const postId = parseInt(req.params.id);
    const comments = await db.any(
      'SELECT * FROM comments WHERE post_id = $1 ORDER BY created_at DESC',
      [postId]
    );
    res.json(comments);
  } catch (error) {
    res.status(500).json({ error: 'An error occurred while fetching comments' });
  }
});

// Add a comment to a post
router.post('/posts/:id/comments', async (req, res) => {
  try {
    const postId = parseInt(req.params.id);
    const { author, content } = req.body;
    const result = await db.one(
      'INSERT INTO comments(post_id, author, content) VALUES($1, $2, $3) RETURNING *',
      [postId, author, content]
    );
    res.status(201).json(result);
  } catch (error) {
    res.status(400).json({ error: 'An error occurred while adding the comment' });
  }
});