An order is shared work. A buyer starts it, a supplier responds to it, and staff may need to step in. All three need to be looking at a state the application can actually support.
Atlas Market puts that workflow around a GTA/FiveM roleplay marketplace. The June 25, 2026 account describes three role-specific dashboards, a defined order lifecycle, and conversation attached to the order. This article follows that implementation account, not a newly audited release.
01 / FIELD NOTESOne API inside the application
The backend is a standalone Hono app mounted inside Next.js through a catch-all route. Next.js handles the pages; Hono handles /api/* requests. The source describes this separation as a way to keep the route logic independent of Next.js internals and test the API on its own.
Neon serverless Postgres stores the records. Clerk supplies authentication, with a Discord-guild allowlist gate on top. Ably handles realtime messaging, and R2 stores images.
ATLAS / RESPONSIBILITIES
The system, with the boundaries left in.
Select a component to read what the supplied account says it does.
Pages & API bridge
Next.js
Next.js handles pages. A catch-all route bridges /api/* to the standalone Hono app.
Next.js: Next.js handles pages. A catch-all route bridges /api/* to the standalone Hono app.
Hono: Owns the API routes and documented order operations; it is mounted inside Next.js, not described as a separate Worker deployment.
Clerk + allowlist: The account names Clerk authentication with a Discord-guild allowlist gate. A complete permission matrix is not supplied.
Neon / Postgres: Order, item, and thread writes share a transaction. Prices use the documented integer-math approach.
Ably: Publishes the notifications after database commit. The excerpt does not establish guaranteed retry or delivery.
R2: Stores images in the documented architecture. The complete upload and delivery pipeline is not included here.
These are responsibilities, not a single chain of services. A database write does not travel through image storage on its way to a notification.
02 / FIELD NOTESModel the lifecycle, not a collection of flags
The documented sequence begins PENDING → ACCEPTED → …, with a 400 response for illegal transitions. The remaining states and permissions are not included in the excerpt; that partial sequence is not a complete transition map.
The point is to make valid changes explicit. An order should not acquire incompatible status flags just because different parts of the application can update them independently.
The account also describes deterministic money calculations, with totals rounded to cents using integer math. That is reported implementation detail; the pricing function itself is not included in this excerpt.
03 / FIELD NOTESThe order, its items, and its thread belong together
Order creation touches three tables. The source wraps those writes in one transaction, returning the order and its conversation thread only after that transaction succeeds.
const result = await withTransaction(async (tx) => {
const [order] = await tx`INSERT INTO orders (...) VALUES (...) RETURNING *`
for (const item of items) {
await tx`INSERT INTO order_items (order_id, item_id, ...) VALUES (...)`
}
const [thread] = await tx`INSERT INTO threads (order_id, ...) RETURNING *`
return { order, thread }
})
// Publish notifications outside the transaction (non-fatal if they fail)
await Promise.allSettled(participants.map((uid) =>
publishToChannel(`user:${uid}:notifications`, 'new_thread', { ... })
))This is an abbreviated source excerpt. Its ellipses and omitted fields are retained; it is not a runnable replacement for the route.
The notification publication comes after withTransaction returns. Promise.allSettled collects the results of the publish attempts rather than putting those attempts inside the database transaction.
ATLAS / TRANSACTION EXPLORER
One commit. Then the message.
Choose a failure case, or step through the boundary between records and notifications.
DATABASE RECORDS
AFTER COMMIT
waitingNotification outcomeValidate the request.
The complete sequence is visible. Writes become durable together at commit; notification failure afterward does not roll them back.
That creates two importantly different failure cases. A failed insert prevents the transaction from committing. A failed notification happens after the database work and does not roll it back.
The excerpt does not show a retry queue, delivery receipt, or recovery process for a missed notification. Separating publication from commit is not the same as guaranteeing delivery.
04 / FIELD NOTESWhat the original tests covered
The write-up reports 97 endpoints and 377 tests across unit, integration, and Playwright end-to-end coverage. It says the order lifecycle and illegal-transition rejections were tested directly.
Those figures describe the June 2026 account. They have not been rerun for this update and should not be read as a measurement of the current deployment.
05 / FIELD NOTESWhat I would tighten next
The original next steps are practical: replace the leftover scaffold package name, bring ad hoc route validation into a shared boundary layer, and align realtime event names with the REST domain so they do not drift apart.
Those were open maintenance tasks at the time of writing. Their later status needs to be checked against the repository.
The later query-remediation article needs one more historical check: its Express-style request-handler excerpt differs from the Hono architecture described here. The available source revisions do not explain that difference.
06 / FIELD NOTESThe boundary worth remembering
The order is committed state. The notification tells someone about that state. Keeping those responsibilities separate makes the failure behavior easier to reason about—and easier to explain to the next person maintaining the system.
Explore the Atlas Market project for the broader workflow, or read the testing essay for the regression-first approach described in the related work.
Source, dates, and what this page verifies
This rewrite is grounded in the supplied project account and complete related articles. Publication dates describe those accounts, not a new release. The original application, its permissions, screenshots, test results, and deployment have not been re-audited.
The diagrams are local explanations with no API calls, database operations, test execution, or saved input. Source conflicts and unsupported outcomes are identified in the reading copy and the handoff. No production deployment occurred.