Software Requirements Specification #
SRS v1.0 · ronilprasad8.tech · Full-Stack Portfolio & AI Assistant Platform
1. Introduction #
1.1 Purpose #
This Software Requirements Specification (SRS) documents the functional and non-functional requirements for
ronilprasad8.tech, a full-stack personal portfolio and AI-powered assistant platform.
The document serves as the definitive reference for what the system does, which external services it depends on,
and what quality attributes it must exhibit.
1.2 Scope #
The system encompasses a public-facing portfolio website with the following major capability areas:
- Static content pages (Home, About, Projects, Contact, Architecture).
- An AI conversational assistant ("The GOAT") with a multi-layered LLM failover engine.
- User authentication (Email/Password signup & login, Google OAuth, password reset) via Firebase.
- Persistent user data and chatbot knowledge storage via Cloud Firestore.
- SEO optimizations including JSON-LD structured data, Open Graph tags, and a sitemap.
- Serverless deployment on Vercel with a Python (Flask) backend.
The scope excludes payment processing, admin dashboards, CMS-managed content, and any native mobile
applications.
1.3 Intended Audience #
| Audience |
Interest |
| Project Owner (Ronil Prasad) |
Authoritative feature catalogue and design rationale. |
| Developers / Maintainers |
Exact behavioral requirements for every route, module, and integration. |
| Academic Reviewers |
SRS artefact for coursework / portfolio assessment. |
1.4 Definitions & Acronyms #
| Term |
Definition |
| GOAT |
The AI assistant persona β "Greatest Of All Time". Implemented as a Python chatbot module. |
| Failover |
Automatic switching from one LLM provider to the next upon failure (e.g. quota exhaustion). |
| Knowledge |
A per-user array of facts persisted in Firestore that are injected into the LLM system prompt to provide
memory across sessions. |
| L1 / L2 / L3 |
Layers of the chatbot failover hierarchy: L1 = Gemini Key 1, L2 = Gemini Key 2, L3 = Groq (Llama 3.3).
|
2. Overall Description #
2.1 Product Perspective #
The system is a standalone, self-contained web application. It is not a module within a larger
enterprise system. It communicates with external services (Firebase, Gemini, Groq, ESPN) via their REST or SDK
APIs but does not expose its own public API for third-party consumption.
Architecturally, the application follows a server-rendered template pattern: Flask serves
Jinja2-rendered HTML pages, with client-side JavaScript modules handling Firebase Authentication, Firestore
data access, and chatbot widget interactions directly from the browser.
2.2 User Classes #
| User Class |
Access Level |
Description |
| Anonymous Visitor |
Read-only (public pages) |
Can browse Home, About, Projects, Contact, Architecture, and download the CV. Cannot use the chatbot.
|
| Authenticated User |
Full interactive access |
All visitor access plus the GOAT chatbot (widget + dedicated page). The chatbot learns and remembers
user-specific facts. |
| Owner (Master) |
Elevated chatbot persona |
Identified by the email ronilprasad46@gmail.com. The chatbot addresses them as "Master",
stores learned facts under a global ronil_global Firestore document, and shows a unique input
placeholder.
|
2.3 Operating Environment #
| Aspect |
Detail |
Source |
| Runtime |
Python 3.x (Flask 3.1.3) via Vercel Serverless Functions |
vercel.json, requirements.txt |
| Client |
Modern browsers (ES Module support required for Firebase SDK v10/v11) |
base.html script imports |
| Hosting |
Vercel (production), Flask dev server on port 5000 (local) |
app.py L97, vercel.json |
| Domain |
ronilprasad8.tech (canonical) |
base.html L14 |
3. Functional Requirements #
3.1 Portfolio & Static Content #
| ID |
Requirement |
Priority |
| FR-001 |
Landing Page (Hero). The / route shall render a hero section displaying the
owner's name,
a typewriter animation cycling through titles ("Software Engineer", "Methodical Planner", "Logician",
"The Flawless Developer"), a subtitle, and two CTA buttons ("View My Logic" linking to USP e-portfolio,
"Get In Touch" linking to /contact). An animated character image (Luffy) with a speech bubble
shall be displayed.
|
High |
| FR-002 |
About Page. The /about route shall render the owner's biography, education
info card
(BSE at USP, Year 3), philosophy card, a "View Resume" button linking to /cv, a categorized
Technical Arsenal section (Languages, Web & Frontend, Backend, AI & APIs, Cloud & Deployment,
Virtualization, Networking & Systems, Tools & IDEs, Version Control β each with badge images), and
an Academic Roadmap section listing specific USP course units.
|
High |
| FR-003 |
Projects Page. The /project route shall display project cards for:
Intelligent Document
Assistant (external link to assistant.ronilprasad8.tech), Socket Programming project (GitHub
repo link), and a general GitHub Repositories card (link to the user's GitHub repos tab).
|
High |
| FR-004 |
Contact Page. The /contact route shall render a social grid with clickable
tiles for
GitHub, Instagram, Facebook, X (Twitter), Email (mailto:), and Phone (tel:).
|
High |
| FR-005 |
Architecture Page. The /architecture route shall document the GOAT
Assistant's
multi-layered failover system, including an explanation of L1 (Gemini Primary), L2 (Gemini Key Rotation),
and L3 (Groq Failover), along with an ASCII-style workflow diagram.
|
Medium |
| FR-006 |
CV Download. The /cv route shall serve the file CV/CV.pdf via
Flask's send_from_directory.
|
Medium |
| FR-007 |
Sitemap. The /sitemap.xml route shall serve a static XML sitemap from the
project root.
|
Low |
3.2 Global Navigation & Layout #
| ID |
Requirement |
Priority |
| FR-008 |
Persistent Navigation Bar. A top navigation bar shall appear on every page (via
base.html),
containing links to Home, About, Projects, and Contact, plus an auth icon button on the right.
|
High |
| FR-009 |
Auth Icon State Toggle. The auth icon shall reactively change based on Firebase
onAuthStateChanged: show a user-circle icon (link to /login) when logged out,
and a sign-out icon (red, triggers signOut() then redirects to /login) when
logged in.
|
High |
| FR-010 |
Footer. A global footer shall display a copyright line with the dynamic current year and
social
links (GitHub, Instagram, Facebook, X).
|
Medium |
3.3 Authentication #
| ID |
Requirement |
Priority |
| FR-011 |
Login/Signup Tabs. The /login page shall present two tabs: "Login" and "Sign
Up",
switchable client-side via switchTab(). The Login tab is shown by default.
|
High |
| FR-012 |
Email/Password Login. Users shall authenticate via
signInWithEmailAndPassword().
On success, a banner displays and the user is redirected to / after 1 second. On failure,
an error banner is shown.
|
High |
| FR-013 |
Google OAuth Login. Users shall authenticate via signInWithPopup() using
GoogleAuthProvider with prompt: 'select_account'. First-time Google users
are auto-registered in Firestore with derived first/last names from displayName.
|
High |
| FR-014 |
Email/Password Registration. The Sign Up form collects: First Name, Last Name, Nickname,
Organization, Email, Password, and Retype Password. Validation includes password match check and
complexity
regex (β₯8 chars, β₯1 uppercase, β₯1 digit, β₯1 special character). On success, a Firestore user document is
created under users/{uid}.
|
High |
| FR-015 |
Forgot Password. A "Forgot Password?" link is shown on the login form. Clicking it
reveals
a separate view with an email input and "Send Reset Link" button. The system calls Firebase's
sendPasswordResetEmail(). A success banner (mentioning the spam folder) is displayed,
and the view auto-returns to Login after 3 seconds. Error handling covers invalid email and
user-not-found.
|
High |
| FR-016 |
Duplicate Email Guard. If registration is attempted with an already-used email, the
system
catches auth/email-already-in-use and displays: "This email address is already linked to an
active account."
|
Medium |
3.4 GOAT Chatbot #
| ID |
Requirement |
Priority |
| FR-017 |
Global Chat Widget. A floating chat launcher icon (bottom-right) shall be visible on all
pages
except /chat. Clicking it toggles a chat container. Clicking outside the container closes it.
|
High |
| FR-018 |
Dedicated Chat Page. The /chat (GET) route shall render a full-page chat
interface.
The global widget is hidden on this page via CSS override. The chat page also requires authentication
(gating
check via onAuthStateChanged).
|
High |
| FR-019 |
Authentication Gating. Both the widget and dedicated chat page shall disable input and
display
a "You must log in" message with a link to /login when no user is authenticated. Input is
re-enabled upon successful authentication.
|
High |
| FR-020 |
Intent-Based Routing. The backend shall classify user messages as "personal" (about
Ronil)
or "general" based on a hardcoded keyword list (50+ keywords including "ronil", "usp", "football",
"anime",
etc.) and intro patterns ("I'm", "my name is", etc.). Personal queries are routed to Gemini; general
queries
(or Gemini failures) are routed to Groq.
|
High |
| FR-021 |
Multi-Key Gemini Rotation. The system shall support comma-separated Gemini API keys in
the
GEMINI_API_KEY environment variable. On a key failure (e.g. 429), the system cycles to the
next key. The model used is gemini-2.0-flash.
|
High |
| FR-022 |
Groq Failover Layer. If all Gemini keys fail, or if the query is classified as "general",
the system shall fall back to Groq's API using the llama-3.3-70b-versatile model.
|
High |
| FR-023 |
Conversation History. The client shall maintain a local array of chat messages (capped at
10)
and send the last 10 entries to the backend with each request. The backend passes these to both Gemini and
Groq for contextual continuity.
|
Medium |
| FR-024 |
Live Context Injection. Before each response, the backend fetches live context including:
current Fiji time (UTC+12), activity/location inference (at university, sleeping, semester break, etc.),
and Bayern Munich match results from the ESPN API (site.api.espn.com). This context is
injected
into the system prompt.
|
Medium |
| FR-025 |
Knowledge Learning & Persistence. If the LLM response contains a
[LEARN_RONIL: <fact>] or [LEARN_USER: <fact>] tag, the client-side
JS extracts the fact, persists it to Firestore under knowledge/{userId} (or
knowledge/ronil_global for the owner), strips the tag from the displayed text, and updates
the local knowledge array. These facts are sent with subsequent requests.
|
Medium |
| FR-026 |
Typewriter Response Animation. Bot responses shall be rendered character-by-character at
~15β20ms per character to simulate typing.
|
Low |
| FR-027 |
Typing Indicator. While waiting for a backend response, an animated three-dot typing
indicator shall be displayed in the chat window.
|
Low |
| FR-028 |
Dynamic Persona (Owner vs. User). When the authenticated user's email matches the
owner's,
the system prompt addresses them as "Master" / "The Sage" and enables the LEARN_RONIL
trigger.
For all other users, it addresses them by their first name (fetched from Firestore) and enables the
LEARN_USER trigger. The widget placeholder text also changes for the owner.
|
Medium |
| FR-029 |
Chat Message Logging (SAVE_TRIGGER). If the LLM response contains a
[SAVE_TRIGGER: {...}] JSON tag, the client shall parse it and write a document to the
Firestore messages collection with username, text, and a
server-generated timestamp.
|
Low |
3.5 SEO & Analytics #
| ID |
Requirement |
Priority |
| FR-030 |
JSON-LD Structured Data. Every page shall include a schema.org/Person
JSON-LD
block in <head> with name, URL, job titles, address, education, and social
sameAs links.
|
Medium |
| FR-031 |
Open Graph & Twitter Cards. Each page shall have OG and Twitter meta tags with
dynamic
title and description derived from Jinja2 blocks.
|
Medium |
| FR-032 |
Vercel Speed Insights. The Vercel Speed Insights script shall be loaded on every page for
web performance analytics.
|
Low |
| FR-033 |
Google Search Console Verification. The /googlec53d9b38dc3c26f5.html route
shall return the Google verification string.
|
Low |
4. Non-Functional Requirements #
| ID |
Requirement |
Priority |
| NFR-001 |
Page Load Time. Static pages (Home, About, Projects, Contact) shall load within 3 seconds
on a standard broadband connection. Vercel's global CDN edge network provides the delivery layer.
|
High |
| NFR-002 |
Chatbot Response Latency. The ESPN API call in get_live_context() uses a
3-second
timeout (timeout=3); on failure, the live context is silently omitted. LLM provider response
time is dependent on Gemini/Groq service performance.
|
Medium |
| NFR-003 |
History Window Cap. Client-side chat history is pruned to the last 10 messages to bound
token consumption and payload size.
|
Medium |
4.2 Security #
| ID |
Requirement |
Priority |
| NFR-004 |
Credential Storage. All API keys (Gemini, Groq, Firebase) are stored in environment
variables
(loaded via python-dotenv in development, Vercel environment variables in production). The
Firebase API key is injected into page templates server-side via Flask's context_processor.
|
High |
| NFR-005 |
Authentication Provider. Authentication is fully delegated to Firebase Authentication.
Passwords are never stored or handled by the Flask backend. The client SDK communicates directly with
Firebase servers over HTTPS.
|
High |
| NFR-006 |
Password Complexity. Registration enforces: minimum 8 characters, at least one uppercase
letter, at least one digit, and at least one special character.
|
High |
| NFR-007 |
No Server-Side Auth Middleware. The Flask backend does not verify Firebase tokens on the
/chat POST endpoint. Authentication gating is enforced client-side only. This means the chat
API
is technically accessible without authentication if called directly.
|
Medium |
4.3 Usability #
| ID |
Requirement |
Priority |
| NFR-008 |
Responsive Layout. All pages shall be usable on desktop and mobile viewports. The base
stylesheet (style.css, 30KB) contains responsive rules.
|
High |
| NFR-009 |
Error Feedback. The login/signup forms use a dual banner system (success = green, error =
red)
with auto-scroll-into-view for error banners. The chatbot displays "Logic uplink failed. Try again." on
network errors.
|
Medium |
| NFR-010 |
Accessibility. The chat send button and social links include aria-label
attributes. Font Awesome icons are decorative only. The emoji favicon uses an SVG text fallback.
|
Medium |
4.4 Reliability & Availability #
| ID |
Requirement |
Priority |
| NFR-011 |
LLM Failover. The chatbot shall remain functional even if the primary AI provider
(Gemini)
is unavailable. The three-tier failover (Gemini Key 1 β Key 2 β Groq) provides redundancy. A hard
fallback message ("The GOAT is currently in a logical deadlockβ¦") is displayed only if all providers fail.
|
High |
| NFR-012 |
Live Context Fault Tolerance. If the ESPN API call fails, get_live_context()
catches the exception and returns an empty string, ensuring the chatbot still responds.
|
Medium |
4.5 Scalability #
| ID |
Requirement |
Priority |
| NFR-013 |
Serverless Scaling. The application is deployed as Vercel Serverless Functions. Scaling
is
handled automatically by the platform (cold starts apply).
|
Medium |
| NFR-014 |
No Rate Limiting. The Flask /chat endpoint does not implement any rate
limiting,
throttling, or request queueing. Under high traffic, this is bounded only by Vercel's concurrency limits
and the LLM providers' own quotas.
|
Low |
5. External Interface Requirements #
5.1 Third-Party APIs #
| Service |
Purpose |
Protocol |
Auth Method |
Source Reference |
| Google Gemini |
Primary LLM for personal queries (model: gemini-2.0-flash) |
REST via google-genai SDK |
API Key (env: GEMINI_API_KEY, comma-separated for rotation) |
chatbot.py L270β276 |
| Groq |
Failover LLM (model: llama-3.3-70b-versatile) |
REST via groq SDK |
API Key (env: GROQ_API_KEY) |
chatbot.py L286β297 |
| ESPN API |
Fetch Bayern Munich (team ID 132) match results for live context |
HTTPS GET (public, no auth) |
None (User-Agent header spoofed) |
chatbot.py L33β34 |
| Firebase Authentication |
Email/Password, Google OAuth, Password Reset |
Firebase Client JS SDK v10/v11 |
Firebase API Key (injected via template) |
login.html, base.html, chatbot.js |
| Cloud Firestore |
User profiles, knowledge persistence, chat message logging |
Firebase Client JS SDK v10/v11 |
Firebase API Key + Auth context |
chatbot.js, login.html, chat.html |
| Vercel Speed Insights |
Web performance analytics |
Client-side JS (CDN script) |
Automatic (Vercel project-bound) |
base.html L170β176 |
5.2 Database (Firestore Collections) #
| Collection |
Document ID Pattern |
Fields |
Written By |
users |
{firebase_uid} |
firstName, lastName, nickname, organization (email
signups only), email, createdAt |
Signup flow (login.html) |
knowledge |
{firebase_uid} or ronil_global |
facts (array of strings) |
Chatbot widget (chatbot.js) |
messages |
Auto-generated |
username, text, timestamp (server) |
SAVE_TRIGGER in chatbot (chatbot.js) |
5.3 External CDN Resources #
| Resource |
URL |
Purpose |
| Font Awesome 6.5.1 |
cdnjs.cloudflare.com |
Icon library for navigation, social links, and chat UI |
| Firebase JS SDK |
gstatic.com/firebasejs/10.12.0/ and 11.0.1/ |
Auth, Firestore (two different SDK versions are in use β see note below) |
| shields.io |
img.shields.io |
Tech stack badge images on the About page |
Note: The codebase uses Firebase JS SDK v10.12.0 in login.html,
base.html, and chat.html, but v11.0.1 in chatbot.js.
While functionally compatible, this version split is not ideal and may cause subtle issues. Consider
unifying to a single version.
6. Constraints & Assumptions #
6.1 Constraints #
| ID |
Constraint |
Impact |
| C-001 |
Vercel Serverless Execution Limit. Vercel's free/hobby tier imposes a 10-second function
execution timeout. LLM calls that exceed this will fail.
|
High β chatbot responses may timeout on complex queries. |
| C-002 |
LLM API Quotas. Both Gemini and Groq enforce rate limits and daily quotas. The key
rotation pattern mitigates this for Gemini but does not eliminate it.
|
Medium β under heavy traffic, all keys may be exhausted. |
| C-003 |
Client-Side Only Auth. Firebase authentication is enforced solely on the client. The
Flask /chat POST endpoint is unprotected server-side.
|
Medium β the chat API could be called programmatically without auth. |
| C-004 |
ES Module Requirement. Firebase SDK imports use ES module syntax
(import ... from). Browsers without ES module support (e.g., IE 11) will not function.
|
Low β IE 11 usage is negligible. |
| C-005 |
Single-Region Deployment. Vercel deploys serverless functions to a single region by
default. Users far from that region may experience higher latency on chatbot responses.
|
Low β static assets are served from CDN edge. |
| C-006 |
Firestore Quotas. The Firebase project (ronilprasad8-5ba1e) is on the free
Spark plan or Blaze plan with appropriate Firestore read/write limits.
|
Medium β database writes (learned facts, message logs) will fail if quota is exceeded. |
6.2 Assumptions #
| ID |
Assumption |
| A-001 |
The Gemini and Groq API keys provided in environment variables are valid and have sufficient quota for
normal traffic levels. |
| A-003 |
The ESPN public API endpoint for Bayern Munich scheduling remains available and structurally stable.
|
| A-004 |
End users will access the site from modern browsers (Chrome, Firefox, Safari, Edge) with JavaScript
enabled. |
| A-005 |
The site traffic is expected to be low-to-moderate (personal portfolio), so the absence of rate limiting
on the chat endpoint is acceptable. |