Skip to content

Conversation

@malinosqui
Copy link
Member

@malinosqui malinosqui commented Nov 3, 2025

This pull request introduces significant enhancements to the Todo API, primarily focusing on data persistence, operational logging, and server robustness.

Key Changes:

  1. File-Based Data Persistence:

    • The todoStore has been refactored to implement file-based data persistence. Instead of storing todos only in memory, they are now loaded from and saved to a JSON file on disk.
    • A new initTodoStore function is introduced, which is called at server startup to load existing todos from data/todos.json by default, or from a path specified by the DATA_FILE environment variable. If the file or directory doesn't exist, it's created.
    • All create, update, and delete operations on todos now trigger an asynchronous save to the data file, ensuring that changes are persisted across server restarts.
    • Dates (createdAt, updatedAt) are serialized to and deserialized from ISO 8601 strings in the JSON file.
    • The .gitignore file was updated to include data/, preventing the persistent data files from being committed to the repository.
  2. Enhanced Request Logging:

    • Every incoming HTTP request is now logged to stdout with details including the HTTP method, request path, response status code, and the duration of the request handling in milliseconds.
    • A global try...catch block was added around the request handling logic to catch unexpected errors, log them to stderr, and return a 500 Internal Server Error response with the request duration.
  3. Graceful Server Shutdown:

    • The server now listens for SIGINT (e.g., Ctrl+C) and SIGTERM signals.
    • Upon receiving these signals, it performs a graceful shutdown, stopping the Bun server cleanly before exiting the process.
  4. New Root Endpoint:

    • A new GET / endpoint has been added, providing a simple welcome message and guiding users to other available routes like /health and /todos.
  5. Updated Documentation:

    • The README.md has been comprehensively updated to reflect these changes, including:
      • Documentation for new environment variables (PORT, DATA_FILE).
      • An explanation of the new persistence mechanism.
      • Listing of the new GET / route.
      • Details on the format of the new request logs.
      • Removal of the previous note about in-memory-only storage.

Technical Context:
The persistence mechanism leverages Bun's native file system APIs (Bun.file, Bun.write) and Node.js's path and fs/promises modules for directory management. The server's fetch handler was refactored to encapsulate request processing within a handle function, allowing for consistent logging and error handling using try...catch blocks. Environment variables are used for flexible configuration of the server port and data file path.

…e-based data persistence in `todoStore`, updated server to initialize and save todos, and improved logging for request handling. Updated README to reflect new configuration options and functionality.
@sartorijr92
Copy link

sartorijr92 commented Nov 3, 2025

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the `@kody start-review` command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration

@reviewOptions

Access your configuration settings here.

bun run src/server.ts
```

> Use `bun run --watch src/server.ts` para modo de desenvolvimento com recarga automática.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Kody Rules high

> For development, use `npm start`. For a containerized environment with auto-reloading, use `docker compose up --build`.

The project's contribution guidelines require using npm start or docker compose for running the application. The command bun run --watch src/server.ts does not follow these standards. Please update the documentation to reflect the standard commands for development to ensure a consistent workflow.

Kody Rule violation: Use npm start ou docker-start, nunca npm run build

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Comment on lines +277 to +283
const shutdown = (signal: string) => {
console.log(`Recebido ${signal}, finalizando...`);
try {
server.stop();
} catch {}
process.exit(0);
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug critical

const shutdown = (signal: string) => {
  console.log(`Received ${signal}, shutting down...`);
  server.stop(true);
};

The current shutdown implementation uses process.exit(0), which forcefully terminates the application. This is risky because it can interrupt ongoing requests, such as writing a new 'todo' to the database file, leading to data corruption or loss.

To ensure data integrity, the server should shut down gracefully. By using server.stop(true), you allow all in-flight requests to complete before the server stops. The process will then exit cleanly on its own once all operations are finished, preventing any data from being left in an inconsistent state.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Comment on lines +124 to 135
async #save() {
if (!this.#dataFile) return;
const data = Array.from(this.#todos.values()).map((t) => ({
id: t.id,
title: t.title,
completed: t.completed,
createdAt: t.createdAt.toISOString(),
updatedAt: t.updatedAt.toISOString(),
}));
await this.#ensureDir();
await Bun.write(this.#dataFile, JSON.stringify(data, null, 2) + "\n");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug critical

#savePromise: Promise<void> = Promise.resolve();

  #save() {
    this.#savePromise = this.#savePromise
      .then(() => this.#doSave())
      .catch((err) => {
        console.error("Error saving data:", err);
      });
  }

  async #doSave() {
    if (!this.#dataFile) return;
    const data = Array.from(this.#todos.values()).map((t) => ({
      id: t.id,
      title: t.title,
      completed: t.completed,
      createdAt: t.createdAt.toISOString(),
      updatedAt: t.updatedAt.toISOString(),
    }));
    await this.#ensureDir();
    await Bun.write(this.#dataFile, JSON.stringify(data, null, 2) + "
");
  }

The current implementation of the #save() method is invoked without being awaited in create, update, and delete. This fire-and-forget approach creates a race condition when multiple modifications happen in quick succession. To fix this, all save operations must be serialized to ensure they execute one after another. This can be achieved by chaining promises. A private property #savePromise can hold the promise for the currently executing or last-scheduled save operation. Each new call to #save() chains its work onto this promise, guaranteeing sequential execution and preventing data corruption.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Copy link

@sartorijr92 sartorijr92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…o support pagination, sorting, and bulk deletion by completion status. Improved JSON body handling with payload size limits and added request ID logging. Updated README to reflect new features and response headers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants