# How Generation Settlement Logic Works in the Awesome‑GPT‑Image‑2 Platform

> Learn how Awesome-GPT-Image-2 handles generation settlement logic using a two-phase lookup-and-settle workflow and atomic stored procedures to reconcile APIMart tasks with PostgreSQL reservations.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: deep-dive
- Published: 2026-09-04

---

**The Awesome‑GPT‑Image‑2 platform handles generation settlement through a two‑phase lookup‑and‑settle workflow that reconciles pending APIMart tasks against PostgreSQL reservations using the `settlePlatformGeneration` helper and atomic stored procedures.**

The Awesome‑GPT‑Image‑2 repository implements a provider‑agnostic architecture for AI image generation, using APIMart as the primary inference backend. When users submit generation requests, the system creates rows in the `generation_reservations` table that must be synchronized with external provider state. This article examines the exact mechanism—implemented across [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js) and [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js)—that finalizes, or "settles," these transactions once APIMart reports a terminal state.

## The Two‑Phase Settlement Architecture

The **generation settlement logic** follows a deterministic two‑phase pattern: first verifying local reservation state, then reconciling with the external provider to ensure consistency between the APIMart task lifecycle and the platform’s internal billing records.

### Phase 1: Local Reservation Lookup and Short‑Circuiting

When a client polls for status via `GET /api/generation/status`, the handler immediately invokes `findPlatformGeneration` (lines 48‑57 in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js)) to query the `generation_reservations` table, filtering by `provider='apimart'` and the APIMart task ID. If the reservation already carries a final status—either `succeeded` or `failed`—the system calls `formatStoredGeneration` (lines 29‑45) to convert the database row into a JSON response and returns it immediately, avoiding unnecessary external API calls.

### Phase 2: External Provider Reconciliation

For reservations still marked `pending`, the handler proceeds to fetch the latest task state from APIMart using `getApimartTask` (lines 56‑63 in [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js)). When this call returns a terminal state—`completed` or `failed`—the trigger is pulled for settlement.

## Core Settlement Implementation

The heart of the logic resides in **`settlePlatformGeneration`**, an async function exported from [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js) that performs three critical operations: updating provider‑specific metadata, persisting the final cost and result URL, and invoking PostgreSQL stored procedures to handle side effects.

### Updating Provider Metadata

First, `settlePlatformGeneration` extracts cost and result metadata via `providerFieldsForTask` (lines 18‑27), which returns an object containing `provider_cost_usd`, `provider_result_url`, and `provider_result_expires_at`. The function then executes an `.update()` query against `generation_reservations`, constrained by `.eq('status', 'pending')` to prevent race conditions.

### Atomic Completion via Stored Procedures

To ensure ACID compliance for billing and quota management, the platform delegates state transitions to PostgreSQL stored procedures defined in [`supabase/migrations/20260828090000_apimart_generation_tasks.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/20260828090000_apimart_generation_tasks.sql):

- **Successful completions**: When `task.status === 'completed'` and an image exists, the handler calls `complete_generation_reservation` (via `client.rpc` at lines 71‑77), passing the reservation ID. This stored procedure marks the reservation as finished and triggers downstream bookkeeping such as user quota debiting.
- **Failure handling**: For failed tasks, the system invokes `release_generation_reservation` (lines 79‑84), optionally passing the APIMart error code to annotate the failure reason in the database.

## Practical Code Examples

### Querying Generation Status (Client Side)

```javascript
// Call the status endpoint with a known APIMart task ID
async function getGenerationStatus(taskId) {
  const resp = await fetch(`/api/generation/status?taskId=${encodeURIComponent(taskId)}`);
  const data = await resp.json();
  if (!data.ok) throw new Error(data.error);
  return data; // contains {status, image, cost, ...}
}

```

### Server‑Side Status Handler (Simplified)

```javascript
// Inside api/generation/status.js
const reservation = await findPlatformGeneration(client, taskId, userId);
if (!reservation) return notFound();

const stored = formatStoredGeneration(reservation);
if (stored) return stored; // already settled

const task = await getApimartTask({ apiKey, taskId });
if (['completed', 'failed'].includes(task.status)) {
  await settlePlatformGeneration(client, reservation, task);
}
return { ...task, user: /* user profile if finished */ };

```

### The Settlement Helper Implementation

```javascript
// Inside api/_lib/generation.js
export async function settlePlatformGeneration(client, reservation, task) {
  if (!reservation || reservation.status !== 'pending') return false;

  await client
    .from('generation_reservations')
    .update(providerFieldsForTask(task))
    .eq('id', reservation.id)
    .eq('status', 'pending');

  if (task.status === 'completed' && task.image) {
    await client.rpc('complete_generation_reservation', { p_reservation_id: reservation.id });
  } else {
    await client.rpc('release_generation_reservation', {
      p_reservation_id: reservation.id,
      p_error_code: task.errorCode || 'GENERATION_FAILED',
    });
  }
  return true;
}

```

## Summary

- **Two‑phase architecture**: The platform first checks the `generation_reservations` table for cached terminal states; if pending, it queries APIMart and triggers settlement only upon detecting a completed or failed task.
- **Centralized settlement logic**: The `settlePlatformGeneration` function in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js) handles all provider‑specific field extraction and database updates, ensuring idempotency via `status='pending'` filters.
- **Database‑driven side effects**: Billing, quota updates, and reservation finalization are executed inside PostgreSQL stored procedures (`complete_generation_reservation` and `release_generation_reservation`) to guarantee atomicity.
- **Provider abstraction**: The design isolates APIMart‑specific details (costs, result URLs) from the core reservation schema, allowing the settlement framework to accommodate additional providers without structural changes.

## Frequently Asked Questions

### What triggers the generation settlement process in Awesome‑GPT‑Image‑2?

The settlement process is triggered automatically when a client or background worker invokes the `GET /api/generation/status` endpoint and the system detects that the corresponding APIMart task has reached a terminal state (`completed` or `failed`). Until that moment, the reservation remains in a `pending` state, and repeated status calls simply return the cached pending record without side effects.

### Why does the platform use PostgreSQL stored procedures instead of application‑level updates?

Stored procedures (`complete_generation_reservation` and `release_generation_reservation`) are used to guarantee atomicity for cross‑cutting concerns like user quota debiting and cost accounting. By encapsulating these side effects inside the database transaction, the system prevents partial updates if the Node.js process crashes mid‑settlement and avoids race conditions when multiple concurrent requests attempt to settle the same reservation simultaneously.

### How does `settlePlatformGeneration` prevent duplicate settlement of the same reservation?

The function includes a guard clause that returns `false` if the reservation status is not `pending`. Additionally, the Supabase update query uses `.eq('status', 'pending')` as a conditional filter, ensuring that even under high concurrency, only the first caller succeeds in transitioning the row, while subsequent attempts affect zero rows and silently exit.

### What specific provider data is captured during settlement?

According to the `providerFieldsForTask` implementation (lines 18‑27 in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js)), the settlement logic extracts and persists three critical fields from the APIMart task object: `provider_cost_usd` (the actual inference cost), `provider_result_url` (the temporary CDN link to the generated image), and `provider_result_expires_at` (the URL expiration timestamp). These fields enable downstream cost analysis and secure image retrieval without repeated calls to the APIMart API.