Personal project · Behind the Project
Antara Halaman
Building the Go backend behind a personal reading journal, with owner-only access, persistent book and chat data, and a Gemini-powered reading companion.

- Context
- Personal reading journal
- Scope
- Backend development & AI integration
- Focus
- Go API · Gemini · PostgreSQL
01 / The idea
What this project is about
The central engineering work in Antara Halaman is the Go API that connects a reading collection to persistent storage and an AI reading companion. It manages books, owner sessions, conversation history, and external AI requests behind a Next.js interface.
The backend separates public browsing from owner-only actions. Visitors can explore the collection, while editing, personal notes, and Teman Baca conversations have different access boundaries. The AI integration builds a controlled request from selected book data and recent conversation history, rather than sending the entire journal to a provider.
Backend & AI / Request flow
How the backend powers Teman Baca
A chat message passes through access checks, book-context selection, provider orchestration, and persistence before the interface displays the result.
- 01
Receive the owner’s request
The interface sends the message, selected book, conversation mode, and spoiler preference to the Go API.
- 02
Validate access and build context
The server checks the owner session, origin, CSRF token, and input. It loads recent conversation history and selected public book fields, leaving private notes and account details out of the model context.
- 03
Check quotas and optional review sources
Persistent per-minute and daily limits bound AI requests. Review mode can use Tavily search with cached results, so repeated searches do not always require another provider call.
- 04
Call Gemini from the backend
Go assembles the mode-specific prompt and bounded context, then calls Gemini with a request timeout. Provider credentials remain on the server.
- 05
Save and return the conversation
Successful replies and their sources are saved with the owner’s conversation. The interface displays the response, and the stored history supports continuing the chat later.
02 / Building it
Building the backend and AI layer
Step 01
Move the collection from browser storage to a Go API
The early frontend stored changes in localStorage. A Go HTTP API with GORM moves books and reading status into a database, adds payload validation, and provides public reads alongside owner-only changes. An explicit import flow carries older browser collections into the database.
Step 02
Implement owner access and session handling
The backend uses Argon2id password hashing, HttpOnly session cookies, hashed session tokens in the database, and origin and CSRF checks for changes. First-owner setup limits registration, while public book responses omit private notes. These checks live on the server rather than relying on hidden interface controls.
Step 03
Build the server-side Gemini integration
Teman Baca supports discussion, mood recommendations, summaries, and review conversations. Go validates the request, selects a bounded set of public book fields, and combines them with recent conversation history and the spoiler preference before contacting Gemini.
Step 04
Add review search and persistent chat history
Tavily search supplies review excerpts and source links for the review flow, with caching to reduce repeated lookups. Conversations and their sources are stored privately, with list, continue, new-chat, and delete actions. Version checks handle conflicting changes from another browser tab.
Step 05
Handle quotas, failures, and backend verification
Database-backed request counters enforce local AI limits, and provider calls have timeouts and bounded response reads. Backend tests use mocked provider responses to exercise quota behavior, private data boundaries, conversation conflicts, deletion, and search-source handling without consuming live AI quota.
Step 06
Adapt the backend for serverless hosting
SQLite remains available for local development, while PostgreSQL through Neon supports hosted persistence. A Netlify Functions adapter preserves HTTP behavior for the Go API. This keeps books, sessions, and chat history in the database rather than depending on a function’s temporary filesystem.
03 / Key decisions
The boundaries behind the experience
Keep the AI provider behind the Go API
The server owns credentials, context selection, request limits, and provider error handling. This gives the application one place to apply its rules before a message reaches Gemini.
Separate public data from private context
Public browsing does not imply permission to edit books or read conversations. The API selects public book fields for AI context and keeps personal notes, account details, and session secrets out of that request.
Make persistence the source of truth
The database holds the collection, sessions, quotas, and successful conversations. Resuming a chat uses stored history, and version checks prevent a stale browser tab from silently replacing newer conversation state.
Distinguish tag matching from generated recommendations
Quick mood suggestions use local book tags. Gemini-powered recommendations are a separate owner feature, with explicit context and quota checks. Review search adds excerpts and links rather than treating a generated answer as a source by itself.
04 / A closer look
Teman Baca and the collection behind it



05 / Looking back
Bringing data, access, and AI together
Moving from browser storage to a backend makes data ownership, persistence, and failure recovery explicit. Book imports, stable URLs, and server-side validation connect interface changes to durable application state.
An AI feature includes context boundaries, provider orchestration, history consistency, and resource limits as well as the prompt itself. Mocked provider tests make those behaviors testable without spending external API quota.
Serverless deployment also changes the persistence boundary: function instances can come and go, so the collection, sessions, and conversations must live in a shared database.
Possible next steps
- Continue improving account recovery and versioned database migrations.
- Evaluate recommendation relevance, review-source quality, and conversation behavior through real use.
Another project, another story
SEA Catering