A continuously evolving, dual-track internship portfolio built with Node.js, Express.js, PostgreSQL, Docker, Docker Compose, and Swagger UI, as part of the FlyRank AI Internship (2026).
This repository is maintained across two parallel internship tracks:
| Track | Focus | Status |
|---|---|---|
| Track 1: Backend AI Engineering Workspace | System architecture, Express.js servers, database layers, validation, containerization, and test evidence | β Active β Weeks 2β6 documented below |
| Track 2: AI Fluency Workspace | Prompt engineering blueprints, model benchmarking, and AI-assisted development tooling | π‘ Scaffolded β content to be published as assignments are completed |
This repository documents the continuous evolution of a backend application developed throughout the FlyRank Backend AI Engineering Internship (2026).
The project began as a simple RESTful CRUD API and is being enhanced incrementally through weekly backend engineering assignments. Each assignment introduces new technologies, architectural improvements, and engineering practices while building upon the previous implementation.
Instead of creating separate repositories for each assignment, this project demonstrates the complete engineering journey β from a beginner-friendly CRUD API toward a more structured, containerized, and production-oriented backend application.
The application is customized with realistic operational workflows from Navigant Education Consultants, illustrating how backend technologies can support education, career development, and future AI-powered digital solutions aligned with:
- π SDG 4 β Quality Education
- π©βπΌ SDG 5 β Gender Equality
This repository showcases progressive backend engineering concepts including:
- API development
- CRUD operations
- REST architecture
- OpenAPI / Swagger documentation
- Database integration and migration
- SQL and parameterized queries
- Repository-based database access
- PostgreSQL
- Environment configuration
- Docker containerization
- Docker Compose
- Persistent Docker volumes
- API testing
- Debugging and troubleshooting
- Git and GitHub workflow
- AI-assisted development and engineering comparison
- Progressive backend architecture
The repository is intentionally maintained as a single evolving project so that the codebase, Git history, documentation, and engineering decisions demonstrate how the application grows throughout the internship.
| Assignment | Week | Status | Key Features Built | Skills & Tools Used |
|---|---|---|---|---|
| BE-01 β Build Your First CRUD API | Week 2 | β Completed | RESTful CRUD endpoints for tasks, JSON request/response handling, route parameters (:id), request validation, correct HTTP status codes |
Node.js, Express.js, REST API design, JSON, API validation, Postman & Swagger UI testing |
| BE-02 β Connecting CRUD API to the Database | Week 3 | β Completed | SQLite β PostgreSQL migration, PostgreSQL repository / data-access layer, automatic table initialization & seeding, parameterized queries | PostgreSQL, pg driver, SQL, parameterized queries, DB Browser for SQLite, repository/data-access pattern |
| BE-04 β Containerize Your Stack | Week 3 | β Completed | Dockerized API + PostgreSQL, Docker Compose orchestration, named persistent volume, verified container-restart persistence | Docker, Dockerfile, Docker Compose, Docker volumes, environment-variable configuration |
| Authentication β Login & Protect (BE-03) | Week 4 | β Completed | Supabase-backed signup / login / logout endpoints, JWT access_token / refresh_token issuance, reusable auth middleware, Swagger bearer-auth integration |
Supabase Auth, JWT, Express middleware, OpenAPI securitySchemes |
| BE-05 β The Polite Scraper | Week 5 | β Completed | Rate-limited, polite scraping pipeline, Zod-validated structured data extraction, generated PDF summary report | Node.js web scraping, Zod schema validation, PDF report generation, nested technical documentation |
| BE-07 β Put an LLM Behind Your API | Week 6 | β Completed | OpenAI SDK wired through OpenRouter's free routing pathway, Stage 0 connectivity script (src/llm/hello.js) |
OpenAI SDK, OpenRouter, Node.js module/environment debugging |
| Assignment A7 β Your First Background Job | Week 6 | β Completed | Out-of-process job orchestration, fast 202 release routing gateway, state polling tracking loops, autonomous chronological cron heartbeat engines | Inngest SDK, Node.js Events, Inngest CLI Local Dev Servers, UUID Generation, Cron Schedules |
This repository is maintained as a single, continuously evolving backend engineering project throughout the FlyRank Backend AI Engineering Internship (2026).
Each assignment extends the existing application rather than creating a completely separate project. This approach demonstrates how the same backend evolves through progressively more advanced engineering concepts, technologies, architecture, testing, documentation, and AI integration.
| Week | Backend AI Engineering Assignment | Status |
|---|---|---|
| Week 2 | BE-01 β Build Your First CRUD API | β Completed |
| Week 3 | BE-02 β Connecting CRUD API to the Database | β Completed |
| Week 3 | BE-04 β Containerize Your Stack | β Completed |
| Week 4 | Authentication β Login & Protect | β Completed |
| Week 5 | The Polite Scraper | β Completed |
| Week 6 | Your First Background Job | β Completed |
| Week 6 | Connect to an AI API | β Completed |
| Week 7 | Build an AI Decision Flow with React Flow + Inngest | β Completed |
| Week 7 | PDF Report Generator | β³ Planned |
| Week 7 | Your first background job | β³ Planned |
| Week 8 | Backend Capstone Documentation & Case Study | β³ Planned |
10-Week Internship Roadmap: The internship is a 10-week learning journey. This table records the backend assignments currently identified in the project roadmap and is updated progressively as each assignment is completed. Future assignments and milestones will be added to the repository as the internship progresses.
Rather than treating each assignment as an isolated exercise, this repository preserves the application's engineering history across the internship.
The project progressively demonstrates:
CRUD API β Database Integration β PostgreSQL β Repository/Data Access β Docker β Persistent Containers β Authentication β AI Integration β Background Processing β AI Workflows β Reporting β Capstone Engineering
This continuous evolution allows the repository to demonstrate not only individual technologies, but also the ability to extend, refactor, test, document, and improve an existing backend system as new engineering requirements are introduced.
Throughout this internship, this repository demonstrates progressive backend engineering experience across API development, databases, containerization, testing, documentation, version control, and AI-assisted engineering.
- β REST API Design
- β CRUD Operations
- β Express.js
- β Node.js Backend Development
- β OpenAPI / Swagger Documentation
- β JSON Request & Response Handling
- β Route Parameters
- β API Validation
- β HTTP Status Codes
- β API Testing with Postman
- β Swagger UI Testing
- β Browser-based API Testing
- β API Debugging & Troubleshooting
- β SQL and Parameterized Queries
- β SQLite Database Integration
- β PostgreSQL Database Integration
- β PostgreSQL Repository / Data Access Layer
- β Environment Variables
- β
.env/.env.example - β Docker
- β Dockerfile
- β Docker Compose
- β Docker Volumes
- β Containerized PostgreSQL
- β Containerized Node.js / Express API
- β Persistent Data Across Container Restarts
- β Git Version Control
- β GitHub Repository Management
- β AI-Assisted Development
- β AI vs Me Implementation Compariso
- β Background Jobs & Event Orchestration
- β Chronological Cron Schedules
As the internship progresses, the same project will be extended to develop additional backend and AI engineering capabilities, including:
- β³ Authentication & Authorization
- β³ AI API Integration
- β³ Web Scraping
- β³ Background Jobs
- β³ AI Workflow Orchestration
- β³ PDF Generation
- β³ Production Deployment
- β³ Additional backend engineering practices introduced through later internship assignments
Progressive Engineering Principle: Skills are marked as completed only when they have been implemented and verified within the project. Future capabilities remain marked as upcoming until the corresponding internship work is completed and evidenced.
- β RESTful CRUD API
- β Node.js backend
- β Express.js server
- β JSON request and response handling
- β
Route parameters (
:id) - β CRUD operations for tasks
- β Request validation
- β Appropriate HTTP status codes
- β API debugging and troubleshooting
- β SQLite database integration during the initial database stage
- β PostgreSQL relational database integration
- β PostgreSQL repository / data-access layer
- β SQL queries
- β Parameterized SQL queries
- β Automatic PostgreSQL table initialization
- β Automatic default task seeding
- β Seeding only when the database is empty
- β Persistent PostgreSQL storage
- β PostgreSQL data preserved across container restarts
- β Dockerized Node.js / Express API
- β Dockerized PostgreSQL database
- β Dockerfile
- β Docker Compose
- β
API + PostgreSQL launched together with
docker compose up - β Named Docker volume for PostgreSQL persistence
- β Containerized development environment
- β Verified application and database container startup
- β Verified database persistence after stack restart
- β Environment-variable based configuration
- β
.envfor local configuration - β
.env.exampleconfiguration template - β
.envexcluded from version control - β Database credentials kept outside committed source code
- β OpenAPI 3.0 specification
- β Interactive Swagger UI documentation
- β Postman API testing
- β
Swagger UI (
Try it out) testing - β Browser testing for GET requests
- β CRUD endpoint verification
- β PostgreSQL persistence verification
- β Git version control
- β GitHub repository management
- β Incremental Git commits
- β README documentation
- β Evidence-based development documentation
- β AI-assisted development
- β AI vs Me implementation comparison
- β Engineering decisions evaluated against an independent AI implementation
- β Realistic Navigant Education Consultants task data
- β Educational and community-oriented workflow examples
- β Project evolution documented as part of the FlyRank Backend AI Engineering Internship
- β Single continuously evolving repository rather than isolated assignment repositories
| Technology | Purpose |
|---|---|
| Node.js | JavaScript runtime for the backend application |
| Express.js | Backend web framework for building the REST API |
| JavaScript | Primary programming language |
| REST API | Backend API architecture and communication style |
| JSON | Request and response data format |
| Swagger UI | Interactive API documentation and endpoint testing |
| OpenAPI 3.0 | API specification and documentation |
| Postman | API endpoint testing and verification |
| SQLite | Initial persistent database used during the earlier database integration stage |
| sqlite3 | Node.js SQLite driver used during the earlier database implementation |
| DB Browser for SQLite | Database inspection and SQL testing during the earlier SQLite stage |
| PostgreSQL | Current relational database used for persistent application data |
pg |
Node.js PostgreSQL client/driver |
| SQL | Database querying and data manipulation |
| Parameterized SQL Queries | Safer database query execution and input handling |
| Repository / Data Access Layer | Separates database operations from the application/API layer |
| dotenv | Loads environment variables from .env |
.env |
Local database and application configuration |
.env.example |
Safe configuration template for project setup |
| Docker | Containerizes the backend application and database environment |
| Dockerfile | Defines the container image for the Node.js API |
| Docker Compose | Orchestrates the API and PostgreSQL services together |
| Docker Volume | Provides persistent PostgreSQL data storage across container restarts |
| Git | Source-code version control |
| GitHub | Remote repository and project history |
| VS Code | Development environment |
| AI Assistant / ChatGPT | AI-assisted learning, development support, debugging, comparison, and engineering reflection |
The Task Management API exposes RESTful CRUD endpoints for creating, reading, updating, and deleting task records stored in PostgreSQL.
| Method | Endpoint | Description | Success Response |
|---|---|---|---|
GET |
/tasks |
Retrieve all tasks | 200 OK |
GET |
/tasks/:id |
Retrieve a specific task | 200 OK |
POST |
/tasks |
Create a new task | 201 Created |
PUT |
/tasks/:id |
Update an existing task | 200 OK |
DELETE |
/tasks/:id |
Delete an existing task | 204 No Content |
GET |
/docs |
Interactive Swagger UI documentation | 200 OK |
The API also handles common invalid requests and missing resources:
| Scenario | Response |
|---|---|
Missing task title on POST |
400 Bad Request |
| Requested task does not exist | 404 Not Found |
Unknown task ID during PUT |
404 Not Found |
Unknown task ID during DELETE |
404 Not Found |
When the Dockerized application is running:
http://localhost:3000
GET http://localhost:3000/tasks
GET http://localhost:3000/tasks/1
POST http://localhost:3000/tasks
PUT http://localhost:3000/tasks/1
DELETE http://localhost:3000/tasks/1
Interactive Swagger UI is available at:
http://localhost:3000/docs
The OpenAPI specification is maintained in:
openapi.json
The API can be tested through Postman, Swagger UI (Try it out), and browser GET requests.
This project demonstrates the evolution of the application's data layer during the FlyRank Backend AI Engineering Internship (2026).
The application initially used SQLite as a lightweight persistent database during the early database integration stage. It was later migrated to PostgreSQL as the project progressed toward a more realistic, containerized backend architecture.
This progression demonstrates an important backend engineering principle: the application can evolve from a simple local database implementation toward a client-server relational database without changing the core purpose of the API.
SQLite was used during the initial database integration stage because it is lightweight, serverless, easy to configure, and well suited to learning relational database concepts in a local development environment.
The SQLite implementation demonstrated:
- Persistent relational data storage
- Automatic database creation
- Automatic table creation
- Default task seeding
- SQL queries
- Parameterized queries
- CRUD operations
- Database persistence across application restarts
- Database inspection using DB Browser for SQLite
The earlier SQLite database was stored locally as:
flyrank-crud-api/
βββ tasks.db
SQLite Initialization
During the SQLite stage, the application automatically:
- Created
tasks.dbif it did not exist. - Created the
taskstable if it did not exist. - Seeded three default tasks when the table was empty.
As the project progressed, SQLite was replaced by PostgreSQL to introduce a more realistic client-server relational database architecture and prepare the application for containerized development.
The current application uses:
- PostgreSQL as the persistent relational database
- Node.js
pgdriver for database communication - Parameterized SQL queries
- A PostgreSQL repository / data-access layer
- Environment-based database configuration
- Dockerized PostgreSQL
- A persistent Docker volume
The PostgreSQL database runs as a separate Docker service from the Node.js API.
Current Architecture
Client
β
βΌ
Node.js / Express API
β
βΌ
PostgreSQL Repository / Data Access Layer
β
βΌ
PostgreSQL Database
β
βΌ
Persistent Docker Volume
This separation allows the API application and database to run independently while communicating through the database connection configured through environment variables.
PostgreSQL Initialization
When the containerized application starts:
- PostgreSQL runs as a Docker service.
- The API connects to PostgreSQL using environment-based configuration.
- The application's
taskstable is initialized when required. - Default Navigant Education Consultants tasks are seeded when the database is empty.
- Existing database records are preserved when the stack is restarted.
The current PostgreSQL setup uses a Docker volume so database data is stored independently of the lifecycle of the PostgreSQL container.
Why PostgreSQL Replaced SQLite
The migration from SQLite to PostgreSQL was part of the project's progression from a learning-focused local database toward a more realistic backend architecture.
PostgreSQL provides a dedicated database server architecture that better represents the type of relational database environment commonly used in production backend systems.
The migration also introduced practical experience with:
- Database connection configuration
- PostgreSQL drivers
- Repository / data-access patterns
- Dockerized databases
- Docker Compose
- Persistent Docker volumes
- Environment variables
- Database service connectivity
- Application and database lifecycle management
Database Persistence
Persistence was verified using the Dockerized PostgreSQL database.
The verification process involved:
- Creating task records.
- Running the API and PostgreSQL through Docker Compose.
- Stopping the application and database containers.
- Starting the stack again.
- Querying PostgreSQL to confirm that previously stored records remained available.
This demonstrated that the data was persisted through the Docker volume rather than being lost when the containers were stopped or recreated.
Engineering Lesson
The database evolution demonstrates that backend architecture is not static.
The project progressed from:
SQLite
β
PostgreSQL
β
Dockerized PostgreSQL
β
Persistent PostgreSQL storage
This progression provided practical experience in replacing a local database implementation with a more production-oriented database while preserving the application's core CRUD functionality.
SQL was used throughout the database stages of the project to inspect, verify, and work with task records.
Current PostgreSQL Query
The current application uses PostgreSQL as its persistent database.
The following query was used to inspect the records stored in the tasks table:
SELECT * FROM tasks;The query can be executed through PostgreSQL using:
docker exec -it flyrank-crud-api-db-1 psql -U postgres -d tasks -c "SELECT * FROM tasks;"This was used to verify that task records existed in the PostgreSQL database and remained available after restarting the Dockerized application stack.
Example Result
The PostgreSQL database was successfully queried and returned persisted task records, including realistic Navigant Education Consultants workflow data.
Example:
id | title | done
----+-----------------------------------------------------------------+------
1 | Prepare SDG 4 education workshop materials | 0
2 | Schedule meeting with women mentors for the LeadHer initiative | 0
3 | Publish Navigant Education Consultants website update | 1
This provided direct evidence that the API was connected to PostgreSQL and that the database contained persistent application data.
Earlier SQLite Stage
During the earlier SQLite database stage, the same SQL concept was tested using DB Browser for SQLite:
SELECT * FROM tasks;This allowed the database records to be inspected directly while learning database persistence and SQL operations.
The project therefore demonstrates the same core database operation across two stages:
SQLite
β
SQL Query
β
PostgreSQL
β
SQL Query
The database technology changed as the architecture evolved, while the core task-management data model and CRUD purpose remained consistent.
The current application uses PostgreSQL as its persistent database and runs PostgreSQL inside Docker.
Database verification was performed by querying the running PostgreSQL container and confirming that task records were stored successfully.
The database verification evidence is maintained in the project's Notion documentation.
PostgreSQL Database Evidence
PostgreSQL Tasks Data
Dockerized PostgreSQL + API
The verification demonstrated:
- β PostgreSQL container running successfully
- β
taskstable available - β Task records stored in PostgreSQL
- β Realistic Navigant Education Consultants task data present
- β Data remained available after restarting the Dockerized stack
- β PostgreSQL persistence provided through the Docker volume
Example verification query:
SELECT * FROM tasks;The project also retains evidence from the earlier SQLite stage, where DB Browser for SQLite was used to inspect and verify the database before the migration to PostgreSQL.
Evidence: Database screenshots and terminal verification outputs are documented in the project's Notion knowledge base.
Earlier SQLite Stage
The project previously used SQLite during BE-02. The following screenshot documents that earlier database stage before the migration to PostgreSQL.
flyrank-crud-api/
β
βββ .gitignore
βββ .env.example
βββ README.md
βββ Dockerfile
βββ compose.yaml
βββ server.js
βββ database.js
βββ openapi.json
βββ package.json
βββ package-lock.json
βββ tasks.db
Key Files
| File | Purpose |
|---|---|
server.js |
Main Node.js / Express application and API routes |
database.js |
PostgreSQL database connection, table initialization, seeding, and database access logic |
openapi.json |
OpenAPI 3.0 specification for the REST API |
Dockerfile |
Defines the Docker image for the Node.js API |
compose.yaml |
Defines and orchestrates the API and PostgreSQL services |
.env.example |
Safe template showing required environment configuration without real credentials |
.gitignore |
Prevents local files and sensitive configuration such as .env from being committed |
README.md |
Project documentation, setup instructions, architecture notes, and engineering progression |
package.json |
Project metadata, dependencies, and npm scripts |
package-lock.json |
Locks the installed dependency versions |
tasks.db |
Earlier SQLite database file from the previous database stage |
Current Runtime Architecture
The current application runs as two Docker Compose services:
Docker Compose
β
βββ API Container
β βββ Node.js + Express
β βββ server.js
β
βββ Database Container
βββ PostgreSQL
βββ Persistent Docker Volume
The earlier tasks.db file is retained in the repository as part of the project's database migration history. PostgreSQL is the current database used by the running application.
Prerequisites
Make sure the following are installed:
- Node.js
- Docker Desktop
- Git
You do not need to install PostgreSQL separately because the current application runs PostgreSQL inside Docker.
Clone Repository
git clone https://github.com/SyedaMun/flyrank-crud-api.git
cd flyrank-crud-apiInstall Dependencies
Install the Node.js dependencies defined in package.json:
npm installThis installs the packages required by the API for local development and ensures that the project's dependency versions are installed according to package-lock.json.
Note: The current Docker workflow also installs the application dependencies inside the API container when the image is built.
Configure Environment Variables
Create a local .env file in the project root using .env.example as the template.
The .env.example file documents the required configuration without exposing real credentials.
Example:
DATABASE_URL=your_postgresql_connection_string
PORT=3000
Security:
.envis intentionally excluded from Git through.gitignore. Never commit real database credentials, passwords, or other secrets to the repository.
Start the Full Stack
The current application is containerized with Docker Compose.
Start the API and PostgreSQL database together with:
docker compose upDocker Compose starts:
- Node.js / Express API
- PostgreSQL database
- Persistent PostgreSQL Docker volume
The API will be available at:
http://localhost:3000
API
Task endpoints are available under:
http://localhost:3000/tasks
Swagger Documentation
Interactive API documentation is available at:
http://localhost:3000/docs
Run in Detached Mode
To start the stack in the background:
docker compose up -dYou can verify the running services with:
docker compose psThe expected services are:
- API container
- PostgreSQL database container
Stop the Stack
To stop the containers:
docker compose downThe PostgreSQL data remains available because the database uses a persistent Docker volume. Stopping the containers does not remove the volume.
Verify PostgreSQL Data
The PostgreSQL database can be queried from inside the running database container:
docker exec -it flyrank-crud-api-db-1 psql -U postgres -d tasks -c "SELECT * FROM tasks;"This can be used to verify that task records exist in the current PostgreSQL database.
Persistence Verification
To verify persistence:
- Start the stack with
docker compose up. - Create task records through the API.
- Stop the stack with
docker compose down. - Start the stack again with
docker compose up -d. - Verify the containers are running with
docker compose ps. - Query PostgreSQL and confirm that the previously created records remain.
This demonstrates that PostgreSQL data persists through application and container restarts because it is stored in the Docker volume.
The Task Management Engine features a modular token-based authentication subsystem leveraging the Supabase identity platform layer. Secure endpoints are guarded utilizing custom interceptive route middleware patterns.
Expanded Security Features
- User Provisioning Gateway (
POST /auth/signup): Handles input format checking and routes records into encrypted offsite database tables. - Cryptographic Token Dispatch Desk (
POST /auth/login): Authorizes user identity details and issues standard JWTaccess_tokenandrefresh_tokenenvelopes. - Session Deactivation Gate (
POST /auth/logout): Destroys active validation strings globally across cloud registries. - Decoupled Verification Middleware (
authenticateUser): A reusable Express interceptor function that dynamically extracts bearer strings from request headers and parses validation states securely. - Interactive Lock Integration: OpenAPI spec configurations extended via
securitySchemesto implement interactive lock controls across the Swagger UI browser dashboard layer.
A rate-limited, "polite" scraping pipeline was built on top of the existing backend to collect and structure book-catalog data end-to-end β from raw HTML collection through to a finished report artifact.
Key features built:
- A staged Stage 0 β Stage 6 scraping roadmap (check-before-you-collect, listing collection, detail-page extraction, cleaning/validation & storage, failure survival & reporting, and evidence publication)
- Zod structural schemas enforcing strict data-typing across every scraped item
- A generated PDF summary report of the scraped catalog data
- A nested
scraper/README.mddocumenting the pipeline architecture and evidence
Skills & tools used: Node.js-based web scraping, Zod schema validation, PDF report generation, resilient/rate-limited request handling, and structured technical documentation.
Full stage-by-stage evidence (screenshots, logs, and milestone checkpoints) for BE-05 is maintained in the project's Notion knowledge base.
The Task Management API features a fully completed, production-ready live LLM connectivity layout. The endpoint ingests unstructured text strings and processes them into strictly typed, validated JSON formats under a fault-tolerant backend layer.
- Input Contract Payload:
{ "text": "string, 1-2000 characters" } - Output Schema Contract Layout:
{ "category": "billing | bug | feature | other", "urgency": "low | normal | high", "confidence": 0.0 - 1.0, "reason": "one short descriptive sentence" } - Strict Guardrails: The system never returns free-form conversational text filler, never hallucinates out-of-bounds enums, and handles unmapped inputs by safely reverting to
"other"with low confidence scores.
- Explicit Client Connection Ceiling: Configured a strict
30000ms(30s) connection ceiling to eliminate hanging thread vulnerabilities. - Automated Exponential Backoff Loop: Built a custom 3-attempt backoff system featuring dynamic delay multiplier scaling and random jitter to handle transient
429rate limits or5xxcloud cluster crashes. - Hardcoded Abort Drop Gates: Enforces early exit sequences to block redundant retry loops whenever encountering unrecoverable client errors (
400,401, or403). - Self-Healing Loop Optimization: Employs an internal fallback parsing retry sequence to automatically hand schema formatting failures back to the model for format remediation.
- Administrative Kill Switch: Reads an environmental property (
LLM_ENABLED=false) allowing developers to immediately divert traffic to local deterministic safety objects during upstream platform outages.
An automated suite executed validation tests sequentially against a static 8-case dataset matrix to calculate accuracy metrics natively under live conditions:
- Total Execution Benchmark Score: 3 / 8 Test Inbound Cases Passed Successfully
- Final Accuracy Metrics Rating: 37.5%
- Evaluation Chronological Date: September 07, 2026
- Assigned Model ID Asset:
openrouter/free
Technical Observation Note:* Failed cases successfully triggered Stage 3 layout exception blocks and gracefully returned structured 422 Unprocessable Entity wrappers, protecting the system core from unclassified text strings or malformed data properties.
- Start the API Application Server:
node server.js
- Run the Automated Evaluation Script (In a Separate Terminal Tab):
node src/llm/evals/runEval.js
- Manual Verification via
curl:curl -i -X POST http://localhost:3000/tickets/classify \ -H "Content-Type: application/json" \ -d '{"text": "Hey! Your app crashed when I tried to pay, and it took my money! Fix this now!"}'
An out-of-process distributed asynchronous workflow engine was mounted onto our Express backend stack using the Inngest framework lane. This architecture implements the high-velocity "accept-fast, process-decoupled, track-status" design pattern used for resource-heavy workloads.
POST /api/reports GET /api/reports/:id Inngest Dashboard (Fast 202 Handshake) (Polling Status Gate) (Port :8288 Console) β β β ββββΊ [Dispatches Event] ββββΊ [Checks Memory Store] ββββΊ [Tracks Execution Graph] β report/generate β pending or complete β Maps retry cascades βΌ βΌ βΌ Responds in <20ms Returns live workflow state Automated 1-Min Cron Heartbeat
- The Fast Door Gateway (POST /api/reports): Ingests execution requests, instantly seeds an in-memory transactional record mapping, dispatches an asynchronous event token to the local runner, and releases the connection chain in under 20 milliseconds by returning an HTTP 202 Accepted handshake wrapper.
- The Status Verification Gate (GET /api/reports/:id): Provides a clean data polling interface layer. It returns a "status": "pending" token string while the report bakes out-of-process, and transforms automatically to "status": "complete" appending compilation payload payloads once finalized.
- say-hello Worker Core: Our initial phase pipeline worker bound to trigger upon receiving incoming test/hello test events.
- generate-report Heavy Baker: Listens to report/generate events, isolates an 8-second execution sleep step without tying up web request threads, and writes successful state records into the tracking store layer.
- cron-heartbeat Scheduled Clock Engine: An autonomous chronological job configured using classic 5-field Unix cron mapping expressions (* * * * *). It boots every 60 seconds automatically on the clock, logging continuous pulses independent of user requests.
- retry-simulation Fault Tolerant Worker: Programmed with restrictive retry parameters (retries: 3) to map error backoff recovery waterfall graphs visually inside our tracking dashboards upon transient failure conditions.
- Spin up the Inngest Background Runner (Terminal Pane #2): npx inngest-cli@latest dev -u http://localhost:3000/api/inngest
- Launch the Core Express API Application Server (Terminal Pane #1): npm start
- Verify Asynchronous Processing Loop Via Postman:
- Submit an HTTP POST request to http://localhost:3000/api/reports to fetch your immediate unique tracking ID string.
- Instantly query GET http://localhost:3000/api/reports/YOUR_ID Cache to watch the status shift dynamically from pending to complete after the 8-second step finishes.
- Navigate your local web browser interface to http://127.0.0.1:8288 to inspect the real-time execution graphs and monitor automated 60-second cron counter logs!
The project has been tested progressively throughout the internship as new backend capabilities were introduced.
The REST API was tested using:
- β Postman
- β
Swagger UI (
Try it out) - β Browser testing for GET requests
The CRUD operations were verified for:
GET /tasksGET /tasks/:idPOST /tasksPUT /tasks/:idDELETE /tasks/:id
The API was also tested against invalid and missing data, including:
- Missing task title
- Non-existent task IDs
- Invalid update requests
- Invalid delete requests
Expected HTTP responses were verified, including:
400 Bad Request404 Not Found201 Created200 OK204 No Content
Database behavior was verified during both the SQLite and PostgreSQL stages.
SQLite Stage
The earlier SQLite implementation was tested using:
- DB Browser for SQLite
- SQL queries
- Application restarts
- CRUD operations
PostgreSQL Stage
The current PostgreSQL implementation was verified using:
- PostgreSQL running inside Docker
- Docker Compose
- PostgreSQL SQL queries
docker exec- Application logs
- Database container logs
Example verification query:
SELECT * FROM tasks;The containerized stack was verified using:
docker compose upand:
docker compose up -dRunning services were verified with:
docker compose psThe expected architecture was confirmed:
Docker Compose
β
βββ API Container
β βββ Node.js + Express
β
βββ Database Container
βββ PostgreSQL
Database persistence was explicitly tested by:
- Creating task records.
- Confirming the records in PostgreSQL.
- Stopping the application and database containers.
- Starting the stack again.
- Querying PostgreSQL after restart.
- Confirming that the previously stored records remained available.
This verified that the PostgreSQL Docker volume was providing persistent storage rather than temporary container storage.
Environment configuration was verified using:
.env.env.example.gitignore
The actual .env file remains local and is not committed to GitHub.
During Stage 6, the implemented solution was also compared with an independently generated AI implementation.
The comparison examined areas including:
- Architecture
- Database handling
- Docker configuration
- Environment configuration
- Repository/data-access design
- Error handling
- Code organization
- Documentation
- Engineering trade-offs
The purpose was not simply to determine which implementation was "better", but to evaluate the differences and use AI as an engineering review and learning tool.
Testing evidence is documented in the project's Notion knowledge base and includes relevant screenshots, terminal outputs, database verification, Docker status, Git status, and AI-assisted engineering comparison evidence.
Through the progressive development of this project during the FlyRank Backend AI Engineering Internship (2026), I have developed practical experience in the following areas:
- Backend application setup and project organization
- Node.js runtime fundamentals
- Express.js backend development
- REST API architecture
- CRUD operations
- HTTP methods and status codes
- Route parameters
- JSON request and response handling
- Input validation
- API error handling
- API debugging and troubleshooting
- Relational database concepts
- SQL queries
- Parameterized SQL queries
- SQLite database integration
- PostgreSQL database integration
- Database initialization and table creation
- Data seeding
- Repository / data-access layer concepts
- Persistent data storage
- Database verification and inspection
- Migration from a lightweight local database to PostgreSQL
- Docker fundamentals
- Writing a Dockerfile
- Containerizing a Node.js API
- Running PostgreSQL in Docker
- Docker Compose
- Multi-container application architecture
- Docker networking between services
- Docker volumes
- Persistent database storage
- Starting and managing a complete backend stack with one command
- Verifying application and database containers
- OpenAPI 3.0
- Swagger UI
- Postman API testing
- Browser-based API testing
- CRUD endpoint verification
- Database persistence verification
- Testing expected error responses
- Evidence-based technical documentation
- Environment variables
.envconfiguration.env.exampletemplates.gitignore- Keeping local credentials outside the public repository
- Understanding the difference between configuration and source code
- Git version control
- Git staging and commits
- Meaningful commit messages
- GitHub repository management
- Git push / pull workflow
- Maintaining a clean working tree
- Incremental project development
- README documentation
- Portfolio-oriented project organization
- Using AI as a development and learning assistant
- Breaking backend tasks into smaller engineering stages
- Using AI for debugging and troubleshooting
- Comparing an independently implemented solution with an AI-generated solution
- Evaluating AI-generated architecture and implementation choices
- Identifying differences, strengths, weaknesses, and trade-offs
- Improving prompts based on implementation results
- Using AI to support engineering reasoning rather than simply copying generated code
The most important outcome of this project is learning how to evolve an existing backend system rather than repeatedly building isolated examples.
The project demonstrates a progression from:
REST API
β
Persistent Database
β
PostgreSQL
β
Repository / Data Access
β
Dockerized Application
β
Dockerized PostgreSQL
β
Persistent Containerized Stack
β
AI-Assisted Engineering Review
This experience has strengthened my understanding of how backend components work together and how engineering decisions affect maintainability, persistence, portability, testing, and future scalability.
Learning principle: The objective of this internship is not only to complete assignments, but to understand the concepts behind each implementation and build a portfolio that demonstrates practical engineering reasoning.
Syeda Munazza Bukhari
Founder β Navigant Education Consultants
Backend AI Engineering Intern β FlyRank AI Internship (2026)
Building practical backend and AI engineering solutions that support education, career development, and digital empowerment.
- GitHub: SyedaMun
- Portfolio: syeda-munazza-bukhari-portfolio.netlify.app
Developed as part of the FlyRank Backend AI Engineering Internship (2026) to strengthen practical backend engineering skills through hands-on project development.


