Md. Nayeem Ahmed
All projects

AgroTrends

A knowledge-sharing platform for agriculture, with an AI advisor that answers questions using the platform’s own articles.

My role
Backend and frontend developer: security, AI features and the React app
Stack
Java 21, Spring Boot 3.5, Spring AI, PostgreSQL, pgvector, React 19
Status
Most of the roadmap is complete. The platform has not launched publicly yet.
Links
Backend codeFrontend code
The AgroTrends stories page with articles on crops and livestock
The stories page running locally with sample articles.

The problem

General AI chatbots can give confident but wrong farming advice, such as an unsafe pesticide dose. Agriculture students and young agronomists in Bangladesh need answers they can verify, in both Bangla and English.

In the earlier version of the project, the AI feature saved articles as embeddings but never used them to answer questions, and authentication and access control needed a full review.

Who it is for

The platform is designed first for agriculture students and recent graduates, then for young agronomists who can become verified experts, and for urban and rooftop growers. It has not launched yet, so it has no users.

What I built

  • Articles with drafts, tags, likes, bookmarks and follows, similar to Medium.
  • A question-and-answer section with voting, reputation and expert badges by topic.
  • An AI advisor that answers from the platform’s articles and shows which ones it used.
  • Secure sign-in, session management and password reset.
  • The React web app in Bangla and English, delivered in more than 130 small pull requests.

Architecture

A layered Spring Boot application on PostgreSQL. Each article is split into chunks of about 800 tokens and stored in pgvector, together with details such as its author, category and publishing status.

questiondaily limitpgvectorGeminianswer + sources
A signed-in user with a confirmed email asks a question of up to 1,000 characters.

Key decisions

Only reviewed content reaches the AI

Drafts and unreviewed AI answers are never used as sources. AI-generated answers to community questions are marked as unchecked until an expert confirms or corrects them, and only then become part of the AI’s knowledge.

Sessions that can actually be ended

Access tokens last 15 minutes and are checked against a stored session on every request. Refresh tokens can only be used once and are replaced each time. When a user signs out, their session really ends.

Permission checks live in the service layer

Every change to content goes through one ownership check in the service layer, so a new endpoint cannot accidentally skip it. Private data returns “not found” rather than “forbidden”, so it does not reveal that it exists.

How I solved it

The original AI feature stored articles but never used them, and the embedding model it relied on had been retired by Google. I switched to a supported model, split articles into chunks with useful metadata, and added a retrieval step before the AI answers:

return RetrievalAugmentationAdvisor.builder()
        .documentRetriever(VectorStoreDocumentRetriever.builder()
                .vectorStore(vectorStore)
                .topK(aiProperties.getRag().getTopK())
                .similarityThreshold(aiProperties.getRag().getSimilarityThreshold())
                .filterExpression(DocumentService.publishedOnly())
                .build())
        .queryAugmenter(blogQueryAugmenter())
        .build();

When an article is edited, its stored chunks are replaced, and when it is deleted they are removed. The AI never cites an article that has changed or no longer exists.

What’s next

  • Move the database schema to Flyway migrations.
  • Run the full application test against a real database in CI using Testcontainers.
  • Add a GitHub Actions pipeline for builds, tests and secret scanning.